Quick start
mkdir my-app && cd my-app
npm init -y
npm i -D poops laxative
npx laxative init # writes poops.json (poops + septic + a form) + the two pages the form needs
npx laxative dev # http://localhost:3000 โ site + /api, one origin
septic arrives as laxative's own dependency โ you never install it separately. poops stays a peer you install yourself.
laxative init scaffolds a poops.json with:
- a
markupblock (poops renderssrc/markupโdist), carryingincludePaths: ["_partials"]so the page can include the generated form by name, - a
septicblock with a publicmessagesresource, - a
build.formsblock that generates themessagesform and redirects a submit to/thanks.
Alongside it come the two pages that make the form work end to end: src/markup/index.html, which includes the form with {% include "messages-form.html" %}, and src/markup/thanks.html, where a submit lands.
It refuses to touch an existing poops.json โ run it in an empty directory, or write the blocks yourself.
Run laxative build to produce dist/ (static site + generated form partials), then laxative serve to serve it with the API in one process.
Commands
| Command | What it does |
|---|---|
laxative init |
scaffold a full-stack poops.json + a page |
laxative dev |
build once, serve site + /api on one origin, rebuild on markup change |
laxative build |
septic build (DB โ markup + forms) โ poops compile โ dist/ |
laxative serve |
production: serve dist/ + /api + /uploads from one process |
PORT overrides the port for dev and serve; it defaults to 3000.
What laxative reads
Three keys of the shared config, and nothing of its own:
| Key | Used for |
|---|---|
markup.out |
the directory served as the static site (default dist) |
markup.in |
the directory dev watches for changes |
septic |
the backend to mount. Absent โ frontend-only: laxative serves the static site and mounts no API |
Every other key belongs to poops or septic, and laxative passes it through untouched.