todo-sqlite
April 9, 2026 · View on GitHub
This project was generated by meshc init --template todo-api --db sqlite.
It is the honest local starter: a single-node SQLite Todo API, a process-backed write rate limiter, generated package tests, and a Dockerfile that packages the binary produced by meshc build .. It does not claim clustered placement, continuity, or operator surfaces.
Project layout
todo-sqlite/
mesh.toml
main.mpl
config.mpl
README.md
Dockerfile
.dockerignore
api/
health.mpl
router.mpl
todos.mpl
runtime/
registry.mpl
services/
rate_limiter.mpl
storage/
todos.mpl
tests/
config.test.mpl
storage.test.mpl
types/
todo.mpl
Local contract
mesh.tomlstays package-only and intentionally omits[cluster]main.mplvalidates local config, creates the SQLite schema, and starts the HTTP server directly- generated tests under
tests/prove the local config and storage contract withmeshc test . /healthreports local SQLite state and rate-limit configuration- all routes run locally; there is no
work.mpl,HTTP.clustered(...), ormeshc clusterstory in this starter
HTTP routes
GET /health— local SQLite + rate-limit configuration snapshotGET /todos— list todos locallyGET /todos/:id— fetch one todo locallyPOST /todos— create from{"title":"Buy milk"}PUT /todos/:id— toggle completionDELETE /todos/:id— delete a todo
Mutating routes (POST, PUT, DELETE) stay local and go through the actor-backed limiter in services/rate_limiter.mpl.
Environment
PORT— HTTP port (8080by default)TODO_DB_PATH— SQLite database path (todo.sqlite3by default)TODO_RATE_LIMIT_WINDOW_SECONDS— limiter window length (60by default)TODO_RATE_LIMIT_MAX_REQUESTS— allowed mutating requests per window (5by default)
Use :memory: only for tests or intentionally ephemeral runs. If you set TODO_DB_PATH, it must be a non-empty path.
Local verification
meshc test .
meshc build .
PORT=8080 \
TODO_DB_PATH=./todo.sqlite3 \
TODO_RATE_LIMIT_WINDOW_SECONDS=60 \
TODO_RATE_LIMIT_MAX_REQUESTS=5 \
./todo-sqlite
Clustered and deployable paths
When you need clustered/runtime-owned execution or a shared-database starter, use one of the explicit paths instead of stretching this SQLite template past its contract:
meshc init --template todo-api --db postgres my-shared-todo
meshc init --clustered my-clustered-app
Docker
Build the Linux binary you want to ship, then package that ./output artifact into the image:
meshc build .
docker build -t todo-sqlite .
Re-run meshc build . before rebuilding the image, and build on the Linux target you plan to run because the Dockerfile copies the already-compiled ./output binary into the container. If you're driving Docker from macOS or Windows, emit ./output from a Linux builder host, CI job, or container first.
Run it with a persisted SQLite volume:
docker run --rm \
-p 8080:8080 \
-e PORT=8080 \
-e TODO_DB_PATH=/var/lib/todo/todo.sqlite3 \
-v todo-data:/var/lib/todo \
todo-sqlite