GioJSdocs
On this page

gio add

Add starter features - Tailwind, an API route, authentication, a database, Docker, CI - to an existing GioJS app, without overwriting files you changed.

npx gio add tailwind auth
bash
gio add <feature...> [--cwd <dir>] [--dry-run] [--force]

Reference

OptionTypeDefaultDescription
<feature...> (required)string-One or more of tailwind, api, auth, db, docker, ci, as separate arguments or comma-separated. Aliases: tailwindcss; database, sqlite, drizzle for db; github-actions for ci. The create flags work too: --auth, --features auth,db.
--cwd <dir>path.The project directory.
--dry-runbooleanfalseShow what would be created and updated; write nothing.
-f, --forcebooleanfalseOverwrite files and package.json scripts that differ from the feature's.
-h, --helpboolean-Print create-giojs add's help, with the feature list, and exit with 0.

Features

FeatureAddsStatic sites
tailwindTailwind CSS v4 through its CLI, rebuilt as you edit (npm run dev runs the watcher).yes
apiA JSON route.ts and a <GioForm> page action (/guestbook).no
authCookie sessions, login and logout, a guarded /dashboard, a rate-limited /login.no
dbDrizzle ORM on Node's built-in SQLite, with migrations (Node 22.16+).no
dockerA production Dockerfile built with gio build standalone, plus docker-compose.yml.no
ciA GitHub Actions workflow: install, typecheck, test and build on every push.yes

Features are always applied in that order, whatever order you name them in. The Starter Features page lists every file each one writes.

Behavior

gio add runs create-giojs add with your arguments, finding create-giojs the way gio migrate does (installed copy first, else the same version through npx / pnpm dlx / bunx, never a release without the subcommand). Then:

  1. It reads the project: package.json must exist, with a gio.toml or an app/ directory. TypeScript or JavaScript comes from tsconfig.json / jsconfig.json; a build script running gio export marks a static site; the package manager comes from the lockfile.
  2. It plans the whole run. A feature that is already set up (all its files exist) keeps your edits and changes nothing. For a new feature, a file of yours in its way is a conflict, and the run stops before anything is written, with a diff.
  3. It writes the files, merges package.json dependencies and scripts, adds gio.toml tables and keys (a project without gio.toml gets one), .env lines, .gitignore lines and a note in AGENTS.md, then prints the next steps.

Examples

Preview a feature

text
$ npx gio add docker --dry-run
Would create:
  docker-compose.yml
  .dockerignore
  Dockerfile
Would update:
  AGENTS.md

Next steps:
  Docker:
    - docker compose up --build   (or: docker build -t my-app .)
    - Server secrets go in .env.production.local (git- and docker-ignored), which docker-compose.yml passes to the container.

Add a feature

text
$ npx gio add api
Did create:
  components/forms.css
  app/(site)/guestbook/page.tsx
  app/api/guestbook/route.ts
  lib/guestbook.server.ts
Did update:
  AGENTS.md

Next steps:
  API route + form:
    - Open /guestbook for the form; the same entries are JSON at /api/guestbook.

When a feature adds dependencies, the output ends with the install command to run (Run `npm install` to install ...); gio add does not install them itself.

A conflict

text
$ npx gio add docker
Nothing was written - these files differ from what the feature adds:
  Dockerfile: exists with different content
      - FROM node:22
      + # syntax=docker/dockerfile:1
      + # Production image for my-app: `gio build standalone` packs the app
      ...

Keep your version (rename or merge it by hand), or rerun with --force to overwrite.

Run it again

text
$ npx gio add auth
Authentication is already set up - nothing to change.

Good to know

  • Exit codes: 0 when the features were added (or previewed, or were already there); 1 when the run was refused - a conflict, a server feature for a static site, no project in the directory; 2 for an unknown option or feature, or no feature at all.
  • A server feature on a static site is refused: Cannot add auth to a static site: it needs the GioJS server (build: gio export has none).
  • --force overwrites conflicting files, but not a page of yours that serves the same URL from another folder: that conflict needs a manual fix.
  • Feature pages go into the app/(site)/ route group and import lib/ by relative path, so a @/* alias of yours does not break them.

Version history

VersionChanges
v0.1.0-beta.8Introduced.