CLI & scaffold
One command — netscript init — lays down a complete, running backend workspace:
shared oRPC contracts, an example service, a Fresh frontend, the plugin registry, a
default cache, and the Aspire orchestration layer. Everything after that is the same
CLI extending the same workspace: netscript plugin install to add a capability,
netscript generate plugins to rewire the registry, netscript db for the database
workflow. The point is not typing speed. It is that every structural decision a
backend needs — where contracts live, how a service registers, how a plugin
contributes, how processes find each other — has already been made, once, in one
conventional shape that both you and a coding agent can read back out of the
workspace itself.
The problem the scaffold solves
Ask a coding agent to "add a backend feature" in an unstructured TypeScript repo and watch where its turns go. Before it writes the feature, it has to decide things: a validation library, a database access pattern, a folder layout, a way to register the new route, a way to start the new process. Each decision is a turn, each turn is a chance to pick differently than last time, and the resulting drift is what you spend review cycles undoing.
A scaffolded NetScript workspace removes that entire class of turns. The layout is
generated, so there is exactly one place a contract goes (contracts/versions/v1/),
one way a service declares itself, one registry through which plugins are discovered
— and the registry is generated from the workspace, not hand-imported, so the
convention is enforced by regeneration rather than by review. When configuration
changes, netscript service generate regenerates the Aspire helper files that wire
services, health checks, ports, and cross-service discovery from your declarative
config — the local topology is derived, not hand-maintained. An agent (or a new
teammate) reads the existing conventions and follows them; the turns go into the
feature.
The everyday flow
Four steps, in a fixed order — Aspire must be up before any db command. The
CLI reference covers each group in depth; the
Quickstart walks the same path end to end in about five minutes.
netscript init my-app --db postgres --service — a workspace with contracts, an example service, the Fresh app, the plugin registry, and the Aspire layer. With a database and a service it generates a real Prisma-backed CRUD contract and an oRPC playground at GET /.
cd aspire && aspire start brings up the database and cache and opens the dashboard at :18888 — the generated resource graph, live.
netscript db init / generate / seed — the Prisma-on-Deno workflow, including every plugin's contributed schema, only after Aspire is up.
netscript plugin install workers, then netscript generate plugins so the registry picks the contribution up.
# Preview the whole scaffold plan without writing a file
netscript init my-app --dry-run
# The fully specified, non-interactive form
netscript init my-app --db postgres --service --service-name users --yes
# Extend the workspace, then regenerate the registry
netscript plugin install workers --name workers
netscript generate plugins
This page is the story; the mechanism lives elsewhere and is linked, not duplicated: the curated command tour is the CLI reference , the exhaustive generated surface is the @netscript/cli reference , and the database order-of-operations is the
Installing a plugin is installing a capability
Plugins are how the scaffold grows: background workers, durable sagas, webhook
triggers, durable streams, and authentication are all installed the same way.
netscript plugin install <kind-or-package> adds the plugin package dependency,
emits workspace-owned glue that imports it (such as workers/mod.ts), and
registers its contributions — the host application never changes. The plugin's
service, runtime, contract, and schema internals stay in the installed dependency;
what lands in your repo is the thin, typed seam you own. After installing, one
netscript generate plugins regenerates the registry so the host discovers the new
contribution statically.
Medusa's Agent Skills docs collapse "install a plugin" and "give an agent a
capability" into the same action — skills are installable units an agent uses
directly. A NetScript plugin carries the same dual reading, one artifact with two
framings: netscript plugin install workers adds a runtime capability (a jobs API
and its isolated background processors, run as separate Aspire resources), and the
typed glue plus generated registry it emits is the convention surface a coding
agent reads to use that capability correctly — no separate integration guide to keep
in sync.
The lifecycle is symmetric and inspectable: netscript plugin list shows what is
registered, netscript plugin doctor sanity-checks the wiring, netscript plugin info <name> runs a plugin's published info command, and netscript plugin remove
unregisters it. Authoring your own follows the same two-tier shape the official
plugins use — netscript plugin new billing scaffolds a JSR-publishable core engine
package and a thin connector that re-exports its contract.
- Add one: Add a plugin — the install flow step by step.
- Author one: Author a plugin — the two-tier core + connector pattern.
- Understand the model: the plugin system — manifest, contributions, generated registries, and why one plugin runs as several processes.
Generated, then owned
Two generation modes coexist in a scaffolded workspace, and knowing which is which tells you what is safe to edit:
- Regenerated artifacts — the plugin registries (
netscript generate plugins), runtime configuration schemas (netscript generate runtime-schemas), and the Aspire helper files (netscript service generate). These are derived from your configuration and re-derived when it changes; treat them as outputs. - Emitted-then-owned code — the glue a
plugin installwrites and the Fresh UI componentsnetscript ui:addcopies into your repo. These are yours from the moment they land: edit them freely, they are never overwritten behind your back.
That split is the scaffold's contract with you: conventions are enforced where regeneration is cheap, and ownership is handed over where your edits are the point. How generated runtime schemas feed the operator-facing override layer is the
runtime configuration story.