Creating a Project#

sigx create scaffolds a new SignalX project. Run it without installing anything:

Terminal
pnpm create @sigx@latest

or, if the CLI is already available, npx sigx create. With no flags you get an interactive wizard; with flags it runs headlessly and never touches the network or your git config unless you ask it to.

A project is composed from your choices rather than copied from a fixed template folder: a kind, a render mode and deploy target for server-rendered apps, a styling preset, and any extras are layered together into the file tree. Every combination is generated from the same set of layers, so a router-plus-i18n SSR app on Cloudflare is as first-class as the plain SPA.

The wizard#

Terminal
pnpm create @sigx@latest

The prompts, in order:

  1. Project name — validated as you type: no path separators, and the directory must not already exist.
  2. How do you want to start?
    • Quick start — web app (SPA) + Tailwind + router + tests. A good default.
    • Mobile app — an iOS and Android app with Lynx and daisyUI components (--kind lynx --styling daisyui). Skips to the package manager question.
    • Customize — the questions below.
  3. What are you building? — the kind.
  4. Rendering and Deploy target — SSR only. Picking vercel-edge prints a heads-up that the Edge runtime is Web APIs only, with no Node built-ins or filesystem in server code.
  5. Styling — skipped for terminal apps, which have no styling option.
  6. Extras — a multiselect showing only the extras your kind, render mode and target actually support. Skipped when none apply.
  7. Package manager — defaults to the one that ran create (from npm_config_user_agent), falling back to the nearest lockfile.
  8. Install dependencies? — defaults to yes.
  9. Initialize a git repository? — defaults to yes, or to no when you are already inside a repository (the prompt says so).
  10. Summary and confirmation. Answering no takes you back through the shape questions once.

Then it scaffolds, installs and initializes git as separate spinner phases, and prints the next steps for your package manager. A failed install never fails the run — the project is written, the tail of the install output is shown, and the install command is added to the next steps so you can retry it yourself. If git is not installed, the repository step is skipped with a note.

Esc or Ctrl+C at any prompt exits with code 130.

Flags combine with the wizard: pass any that shape the project and it skips the How do you want to start? question and uses your flags as the prompts' initial values.

To print the options without scaffolding anything:

Terminal
pnpm create @sigx@latest -- --help

Headless mode#

create runs headlessly — no prompts — when any of these is true:

  • stdin or stdout is not a TTY (CI, or piped output),
  • -y / --yes is passed,
  • a kind is given (--kind, --type or --preset) together with a positional name.

Headless never installs dependencies and never initializes git unless --install / --git say so, which keeps it safe in CI.

Terminal
sigx create my-app --kind ssr --render resume --target cloudflare \
  --styling tailwind --features server-fn,testing --pm npm -y

Flags#

FlagValuesDefaultDescription
name (positional)a directory namemy-sigx-appTarget directory, created under the current folder.
--kindspa, ssr, ssg, terminal, lynxspaWhat to build. See Kinds.
--typebasic, ssr, ssg, terminal, lynx—Deprecated alias of --kind; basic means spa. Giving both with different values is an error.
--renderhydrate, islands, resumehydrateSSR only. See Render modes.
--targetnode, cloudflare, bun, deno, vercel, vercel-edge, netlifynodeSSR only. See Deploy targets.
--stylingnone, tailwind, daisyuinoneStylesheet preset. Terminal apps take none.
--featurescomma-separated: router, i18n, testing, server-fn—Extras. See Extras.
--pmpnpm, npm, yarn, bun, denodetectedPackage manager the scripts and next steps are written for.
--install / --no-install—off in headlessInstall dependencies after scaffolding.
--git / --no-git—off in headlessgit init plus a first commit.
--presetquick—SPA + Tailwind + router + testing.
--yes / -y——Skip the prompts.
--list——Print every kind, render mode, target, styling and extra this build can generate, then exit.
--help / -h——Print the options and a few examples, then exit without scaffolding.

--render and --target apply to --kind ssr only; passing them with any other kind is an error.

Exit codes — 2 for an invalid or contradictory flag, 1 when scaffolding itself fails (for example the target directory already exists), 130 when you cancel a prompt.

To see exactly what your installed version can generate:

Terminal
sigx create --list

Kinds#

--kindWhat you get
spaClient-rendered single-page app on Vite.
ssrServer-rendered web app — streaming, islands or resumable, deployable to seven targets.
ssgStatic site with @sigx/ssg — file-based routing, MDX, built-in search.
terminalTerminal UI with @sigx/terminal — TSX + signals, HMR dev runner.
lynxNative iOS and Android app with SignalX Lynx from one component tree.

basic is the legacy name for spa and still works through --type.

What each kind generates#

Every project ships a README.md describing its layout, scripts and how to deploy, plus a .gitignore — with commands spelled for the package manager you chose.

spa

index.html  vite.config.ts  tsconfig.json  package.json
src/main.tsx  src/App.tsx  src/components/Counter.tsx  src/styles.css  src/env.d.ts
public/favicon.svg

dev → vite, build → vite build, preview → vite preview.

ssr (target node shown)

index.html  server.mjs  vite.config.ts  tsconfig.json  package.json
src/entry-server.tsx  src/entry-client.tsx  src/App.tsx
src/components/Counter.tsx  src/styles.css  src/env.d.ts
public/favicon.svg

src/entry-server.tsx exports a per-request createApp(url) factory — each call builds a fresh app, so nothing is shared between concurrent requests. server.mjs is plain Node with two modes: Vite middleware plus createDevRequestHandler in dev, and static assets plus createRequestHandler over dist/server/sigx-app.js in production. Crawlers and AI agents are served the blocking document render; everyone else gets the streaming one.

dev → node server.mjs, build → vite build --app (one build for client and server), start → node --conditions production server.mjs.

ssg

ssg.config.ts  vite.config.ts  tsconfig.json  package.json  pnpm-workspace.yaml
src/pages/index.mdx  src/pages/about.mdx  src/layouts/default.tsx
src/components/Counter.tsx  src/styles/global.css  src/env.d.ts
public/favicon.svg

The stylesheet stays at src/styles/global.css and @sigx/ssg generates the HTML template. dev / build / preview map to sigx dev / sigx build / sigx preview.

terminal

tsconfig.json  package.json  pnpm-workspace.yaml
src/main.tsx  src/App.tsx

dev → sigx-terminal-dev src/main.tsx (HMR), start → tsx src/main.tsx, plus a typecheck script.

lynx

lynx.config.ts  signalx.config.ts  tsconfig.json  package.json
src/main.tsx  src/main.thread.tsx  src/App.tsx  src/lynx-env.d.ts
assets/icon.png  assets/splash.png  assets/adaptive-foreground.png

The app starts on the Lynx release line your CLI was released against, with @sigx/lynx and every @sigx/lynx-* package on one caret range, so it can declare a typed, per-variant env in signalx.config.ts from the start.

--styling tailwind and --styling daisyui add tailwind.config.ts, postcss.config.js and src/styles.css; daisyUI also adds @sigx/lynx-daisyui and wraps the app in its ThemeProvider. With --pm pnpm, a pnpm-workspace.yaml allows the esbuild and sharp install scripts (see below).

ScriptRuns
devsigx dev
buildsigx build
doctorsigx doctor
native:prebuildsigx prebuild
run:android / run:ios / run:websigx run:android / sigx run:ios / sigx run:web

The native prebuild script was named prebuild before @sigx/cli 0.13. npm runs a script with that name as a pre-hook of build, so every npm run build regenerated the Android and iOS projects. In an older app, rename it to native:prebuild.

The next steps are npx sigx doctor and npm run run:android, spelled for your package manager (for example pnpm exec sigx doctor and pnpm run:android). sigx is a local dev dependency, so it runs through the package manager rather than as a bare sigx. See the Lynx getting-started guide for the toolchain.

Render modes#

SSR projects choose how the page reaches the browser.

--renderBehaviour
hydrateStreaming SSR with full client hydration — the classic shape. The default.
islandsA server-only page whose components hydrate individually per client:* directive, with an app-less hydrateIslands() client. See @sigx/ssr-islands.
resumeZero JavaScript on load; handlers are extracted into chunks and load on first interaction, with refreshComponents and createBoundaryRefresh wired for single-flight boundary refresh. See @sigx/resume.

Deploy targets#

Each target contributes its platform entry, its config, the Vite adapter, and deploy / start scripts, plus a deploy section in the generated README.

--targetEntry & configRun / deploy
node (default)server.mjs (Express)node --conditions production server.mjs
cloudflaresrc/entry.cloudflare.ts, wrangler.jsoncwrangler deploy (wrangler dev to preview)
bunserver.bun.tsbun --conditions=production server.bun.ts
denosrc/entry.deno.ts, deno.jsondeno deploy
vercelsrc/entry.vercel.tsvercel deploy --prebuilt
vercel-edgesrc/entry.vercel.ts (Edge runtime)vercel deploy --prebuilt
netlifysrc/entry.netlify.ts, netlify.tomlnetlify deploy --prod --no-build

Every target develops the same way. dev is always the Vite dev server through server.mjs, whichever platform you deploy to — the platform entry is what build bundles and deploy ships. Express is a dev-only dependency everywhere except the node target.

vercel-edge runs on the Edge runtime: Web APIs only, no Node built-ins and no filesystem in server code.

For the platforms themselves, see the deployment guides.

Extras#

--features takes a comma-separated list; the wizard offers the same set as a multiselect, filtered to what your other choices support.

FeatureAddsAvailable for
router@sigx/router, src/router.ts, Home/About pages, <RouterView />, createWebHistory in the browser and a per-request createMemoryHistory on the serverSPA, SSR (hydrate)
i18n@sigx/i18n, an app namespace in English and Swedish under src/locales/, lazy catalogs, ?lang=/cookie/browser detection, SSR preload and state transfer, a language switchSPA, SSR (hydrate)
testingVitest on happy-dom and oxlint, test and lint scripts, vitest.config.ts, .oxlintrc.json, and a sample test that mounts the app (or the Counter island on a static site)SPA, SSR, SSG
server-fn@sigx/server, src/api/hello.server.ts declared with serverFn, read from a component with useData, and sigxServer() in vite.config.tsSSR (any render mode or target)

Router and i18n need a hydrated client, which is why they are hydrate-only — islands and resumable pages have no client app to route. Server functions compose into whichever platform entry you chose, so a plain hydrated app ships none of that code.

An extra that your kind, render mode or target cannot take is an error, not a silent no-op.

Versions and install scripts#

Generated projects pin the matched sigx / @sigx/* set that your CLI was released against — never latest — so a fresh project's peer graph resolves to a single copy of @sigx/reactivity under strict peer deps. Third-party dependencies (vite, express, tailwindcss, …) keep their own caret ranges. The current CLI is v0.14.0.

TypeScript. Web, SSR, SSG and terminal projects scaffold on TypeScript 7 (typescript ^7.0.2, the native tsc), and their typecheck script runs it. Lynx projects stay on TypeScript 6 (^6.0.3): the Lynx build tool, @lynx-js/rspeedy, declares a typescript peer range of 5.1.6 - 6.0.x and loads lynx.config.ts through the TypeScript JS API, which TypeScript 7 doesn't ship. Keep a Lynx app on TypeScript 6 until the templates move.

Some projects need dependencies to run their install scripts: esbuild for SSG and terminal projects, and esbuild plus sharp for Lynx apps. With pnpm they ship a pnpm-workspace.yaml declaring them under both spellings — allowBuilds for pnpm 11, onlyBuiltDependencies for pnpm 10. Without it pnpm skips the scripts, and pnpm 11 fails the install outright (ERR_PNPM_IGNORED_BUILDS).

If you scaffold inside an existing pnpm workspace, @sigx/* dependencies in the generated package.json are rewritten to workspace:*.

Where to go next#

  • Commands — every command with its usage and flags.
  • Deployment — the platform guides behind each --target.
  • Installation — which plugin package provides which command.