Build data-driven apps with markdown
Tinkerdown is a CLI tool for creating interactive, data-driven applications using markdown files. Connect to databases, APIs, and files with zero boilerplate. Built on LiveTemplate.
AI app builders generate React projects with dozens of files, dependency trees, and build pipelines. When something breaks — and it will — you're debugging code you didn't write, burning tokens trying to fix context window drift, and wrestling with framework complexity that has nothing to do with your actual problem. Tinkerdown takes a different approach: the entire app is a single markdown file. There's no build step, no node_modules, and nothing to drift out of sync.
- Tiny surface area for AI. A Tinkerdown file is declarative — data sources in YAML, layout in markdown, interactions via HTML attributes. There's no component tree to get tangled, no state management to misconfigure, no async rendering bugs. The format is constrained enough that LLMs get it right consistently, and small enough that you can read the whole thing and understand it.
- One file = one app. Data connections, layout, and interactions all live in one markdown file. No scaffolding, no boilerplate. Once you have something useful, it's already a file you can stash in a repo and pull up months later.
- Start simple, add power as needed. Pure markdown gets you surprisingly far — task lists become interactive checkboxes, tables become editable grids. When you outgrow that, add YAML frontmatter for external databases, or drop to HTML + Go templates for full control.
- 8 data sources out of the box. SQLite, PostgreSQL, REST APIs, JSON, CSV, shell commands, markdown files, and WASM. Point at your existing infrastructure — a database, a cluster, an internal API — and have a working UI without writing any glue code.
- Git-native and self-hosted. Plain text in a repo means you get version history, search, offline access, and collaboration for free. No subscriptions, no platform lock-in.
- Made for disposable software. The admin panel for this sprint. The tracker for that hiring round. The runbook for on-call week. Software you'd never justify scaffolding a React project for, but that's genuinely useful for a few days or weeks. When you're done, the markdown is still readable on its own.
# Install
go install github.com/livetemplate/tinkerdown/cmd/tinkerdown@latest
# Create a new app
tinkerdown new myapp
cd myapp
# Run the app
tinkerdown serve
# Open http://localhost:8080Write a single markdown file with frontmatter configuration:
---
title: Task Manager
sources:
tasks:
type: sqlite
path: ./tasks.db
query: SELECT * FROM tasks
---
# Task Manager
<table lvt-source="tasks" lvt-columns="title,status,due_date" lvt-actions="Complete,Delete">
</table>
<form lvt-submit="AddTask">
<input name="title" placeholder="New task" required>
<button type="submit">Add</button>
</form>Run tinkerdown serve and get a fully interactive app with database persistence.
- Single-file apps: Everything in one markdown file with frontmatter
- 8 data sources: SQLite, JSON, CSV, REST APIs, PostgreSQL, exec scripts, markdown, WASM
- Auto-rendering: Tables, selects, and lists generated from data
- Real-time updates: WebSocket-powered reactivity
- Zero config:
tinkerdown servejust works - Hot reload: Changes reflect immediately
Define sources in your page's frontmatter:
---
sources:
tasks:
type: sqlite
path: ./tasks.db
query: SELECT * FROM tasks
users:
type: rest
from: https://api.example.com/users
config:
type: json
path: ./_data/config.json
---| Type | Description | Example |
|---|---|---|
sqlite |
SQLite databases | lvt-source-sqlite-test |
json |
JSON files | lvt-source-file-test |
csv |
CSV files | lvt-source-file-test |
rest |
REST APIs | lvt-source-rest-test |
pg |
PostgreSQL | lvt-source-pg-test |
exec |
Shell commands | lvt-source-exec-test |
markdown |
Markdown files | markdown-data-todo |
wasm |
WASM modules | lvt-source-wasm-test |
Generate HTML automatically from data sources:
<!-- Table with actions -->
<table lvt-source="tasks" lvt-columns="title,status" lvt-actions="Edit,Delete">
</table>
<!-- Select dropdown -->
<select lvt-source="categories" lvt-value="id" lvt-label="name">
</select>
<!-- List -->
<ul lvt-source="items" lvt-field="name">
</ul>See Auto-Rendering Guide for full details.
| Attribute | Description |
|---|---|
lvt-source |
Connect element to a data source |
lvt-click |
Handle click events |
lvt-submit |
Handle form submissions |
lvt-change |
Handle input changes |
lvt-confirm |
Show confirmation dialog before action |
lvt-data-* |
Pass data with actions |
See lvt-* Attributes Reference for the complete list.
Recommended: Configure in frontmatter (single-file apps):
---
title: My App
sources:
tasks:
type: sqlite
path: ./tasks.db
query: SELECT * FROM tasks
styling:
theme: clean
---For complex apps: Use tinkerdown.yaml for shared configuration:
# tinkerdown.yaml - for multi-page apps with shared sources
server:
port: 3000
sources:
shared_data:
type: rest
from: ${API_URL}
cache:
ttl: 5mSee Configuration Reference for when to use each approach.
Tinkerdown works great with AI assistants. Describe what you want:
Create a task manager with SQLite storage,
a table showing tasks with title/status/due date,
a form to add tasks, and delete buttons on each row.
See AI Generation Guide for tips on using Claude Code and other AI tools.
Getting Started:
Guides:
Reference:
Planning:
git clone https://github.com/livetemplate/tinkerdown.git
cd tinkerdown
go mod download
go test ./...
go build -o tinkerdown ./cmd/tinkerdownMIT
Contributions welcome! See ROADMAP.md for planned features and current priorities.