baguette

CLI

The baguette CLI does two jobs: it scaffolds new files in the right place with the right shape (baguette new), and it enforces the clean-code contract in CI (baguette check). Between them, there is one obvious way to add code and a hard gate that keeps it clean.

baguette new

Scaffold structure instead of freehanding it. new writes a file at the conventional location with the correct boilerplate, so routes, cron jobs, and automations always start consistent.

baguette new route <path>
baguette new cron <name>
baguette new automation <name>

Routes

baguette new route customers/create

Creates api/customers/create.ts with a defineRoute skeleton mounted at /api/customers/create. The path argument mirrors the URL, and dynamic segments use bracket syntax:

baguette new route customers/[id]
# -> api/customers/[id].ts  ->  /api/customers/{id}

Cron

baguette new cron sendReminders
# -> cron/sendReminders.ts

Scaffolds a defineCron job with a schedule placeholder.

Automations

baguette new automation onPaymentPaid
# -> automations/onPaymentPaid.ts

Scaffolds a defineAutomation handler wired to an event channel.

baguette check

baguette check verifies your app against the clean-code contract and exits non-zero on a violation. Wire it into CI so code that breaks the conventions can't merge.

baguette check
$ baguette check

  api/customers/create.ts
    warn  hardcoded path — derive it from the file location
    warn  manual c.req.json() — declare a request.body schema

  api/legacy/proxy.ts
    error  'as any' in app code — the framework is missing a type

  2 warnings · 1 error · 14 routes clean

It flags the same patterns the baguette/eslint preset does — hardcoded paths, manual body reads, as any / as never in app code, console.log in handlers, and more — so a human review and an automated review reach the same verdict.

Typical workflow

# scaffold
baguette new route orders/[id]

# ...write the schemas and handler...

# verify before you commit
baguette check