create-package CLI

@tinycld/create-package is the scaffolder for new sibling packages. One command produces a repo that already passes the app shell’s generator checks, CI, and typecheck. It can run interactively (prompts for everything) or fully non-interactively (every prompt has a matching flag).

Usage

npx @tinycld/create-package <slug>

The positional argument is the package slug — kebab-case, 3–40 characters. It becomes:

Omit the positional to be prompted for it.

Flags

Every prompt has a matching flag. Pass --yes to take defaults for everything else.

FlagTypeDescription
<slug>positionalPackage slug. Required when --yes is set; otherwise prompted.
--yes, -ybooleanSkip all prompts and use defaults. Requires the positional slug.
--namestringHuman-readable name. Defaults to title-cased slug.
--descriptionstringOne-sentence description.
--presetfull | settings-onlyDefaults to full under --yes.
--iconstringLucide icon name. Full preset only. Default box.
--nav-ordernumberInteger 0–99. Full preset only. Default 20.
--shortcutstringSingle lowercase letter, or empty. Full preset only.
--server, --no-serverbooleanInclude the Go server stub. Full preset only. Default true.
--targetstringOutput directory. Default depends on the cwd: if a tinycld/ app shell exists as a child, defaults to ./<slug>/; otherwise to ./tinycld-<slug>/<slug>/ (bootstrap mode — see below).
--link, --no-linkbooleanLink the new package into the app shell. Without either, you’ll be prompted; under --yes, defaults to linking.

--no-link always wins over --yes — pass both when you want to scaffold without touching the app shell.

Non-interactive example

npx @tinycld/create-package my-feature \
    --yes \
    --preset full \
    --icon check-square \
    --no-server \
    --no-link

This scaffolds with all defaults, no Go server, and no app-shell linking. Suitable for CI, scripted setups, and autonomous coding agents.

Workspace detection

When --target is not set, the scaffolder picks one of two layouts based on the current directory:

This means npx @tinycld/create-package my-todo from an empty directory produces a self-contained ./tinycld-my-todo/ workspace with everything you need to run the app, while running it from inside an existing ~/code/tinycld/ workspace just adds another sibling package next to your existing tinycld checkout.

The detection check is strict: it reads tinycld/package.json and matches name === "tinycld". A coincidentally-named directory won’t false-match.

Prompts (interactive mode)

PromptExampleNotes
Package slugmy-featureSkipped if passed as argv. Validates kebab-case; minimum 3 chars.
Human-readable nameMy FeatureDefaults to title-cased slug. Used in manifest name and nav label.
One-sentence descriptionDoes a thing well.Used in manifest description, package.json, and README.md.
Presetfull or settings-onlySee Presets.
Lucide iconboxFull preset only. Any lucide-react-native name. Default box.
Nav order20Full preset only. Integer 0–99; controls sidebar position.
Keyboard shortcutfFull preset only. Single lowercase letter, or blank.
Include Go server?y / nFull preset only. If n, server/ and the manifest’s server field are omitted.
Target directory../my-featureDefaults alongside tinycld/. Must not exist or must be empty.
Link into app shell?y / nIf yes, the scaffolder clones tinycld/tinycld (shallow) next to your new package and runs packages:link.

Presets

full — data package

The shape of @tinycld/contacts, @tinycld/mail, @tinycld/calendar, @tinycld/drive. You get routes, a sidebar, an optional provider, pbtsdb collections, PocketBase migrations, seed data, and (optionally) a Go server stub.

settings-only — service package

The shape of @tinycld/google-takeout-import. The package contributes a single Personal Settings panel — no routes, no nav entry, no collections, no server. Use this for integrations and admin-style tools.

Generated files

Both presets produce:

The full preset additionally produces:

The settings-only preset additionally produces:

After scaffolding

The CLI prints the steps it didn’t run — it never touches git or gh. Typical next steps:

cd my-feature
git init
git add .
git commit -m 'chore: initial scaffold'
gh repo create tinycld/my-feature --public --source=. --push

If you didn’t pass --link (or said no to the prompt), also link the package now:

cd ../tinycld
npm run packages:link ../my-feature
npm run checks

Linking the new package into the app shell is enough to see it in navigation; the generator wires routes, collections, migrations, and settings panels automatically.

Import conventions in scaffolded code

Templates use the scoped @tinycld/core path:

import { useOrgLiveQuery } from '@tinycld/core/lib/use-org-live-query'
import { Modal } from '@tinycld/core/ui/modal'

@tinycld/core isn’t a separate npm package or git repo — it’s bundled inside the app shell at tinycld/packages/@tinycld/core/. Resolution works because the sibling compiles in the app shell’s tsconfig context once linked.

Intra-package imports use relative paths; ~/tinycld/<slug>/* is also aliased to the package’s own nested source if you want an absolute form.

For the published source and template internals, see the create-package repo.