CLI Package
Scaffolding CLI. Downloads, renames, and configures TNTStack projects.
Published to npm as @tntstack/create-app. Downloads the latest source, renames all identifiers to match your project, configures Android and iOS packaging, inits git, and optionally installs dependencies.
Usage
npm create @tntstack/app@latestpnpm create @tntstack/app@latestyarn create @tntstack/appbunx @tntstack/create-appThe CLI runs in interactive mode by default. You can also pass flags for CI or scripted setups:
npm create @tntstack/app@latest --name <your-project-name> --github-user <your-github-username> --no-install| Flag | Description |
|---|---|
-n, --name <name> | Project name |
-d, --directory <dir> | Output directory (defaults to ./<name>) |
-g, --github-user <user> | GitHub username or org |
-i, --identifier <id> | App identifier, reverse-domain (defaults to com.<name>.app) |
-v, --app-version <ver> | Initial version (defaults to 0.1.0) |
--no-install | Skip pnpm install |
Directory Structure
How It Works
The scaffold pipeline runs 5 steps in order:
import { downloadTemplate } from "giget";
import { TEMPLATE_SOURCE } from "../consts.js";
export async function cloneTemplate(directory: string): Promise<string> {
const { dir } = await downloadTemplate(TEMPLATE_SOURCE, {
dir: directory,
force: true,
});
return dir;
}Downloads the latest source from github:odest/tntstack#master using giget. No git history is carried over.
The most complex step. Walks every text file in the project and applies find-replace for these identifiers:
| Search term | Replaced with |
|---|---|
com.tntstack.app | User's app identifier |
tntstack_lib | <project_name_snake>_lib |
TNTStack | PascalCase project name |
odest | User's GitHub username |
tntstack | User's project name |
After file contents, it also:
- Renames Android Java package directories (
gen/android/**/java/com/tntstack/→ user's identifier path) - Renames Apple generated directories and files (
gen/apple/) - Updates version fields in all
package.jsonfiles,Cargo.toml,Cargo.lock,tauri.conf.json, and.release-please-manifest.json
Binary files, lock files, and build artifacts are skipped via pattern matching.
Removes files that only belong to the source repo:
export const FILES_TO_CLEAN = [
"CHANGELOG.md",
"packages/cli",
".github/FUNDING.yml",
".github/workflows/publish-cli.yml",
] as const;Also removes packages/cli references from release-please-config.json and .release-please-manifest.json.
Runs git init and creates an initial commit. Skipped gracefully if git is not available.
Runs pnpm install unless --no-install was passed. Falls back with a warning if pnpm is not found.
Interactive Prompts
In interactive mode, the CLI asks these questions:
| Prompt | Default |
|---|---|
| Project name | <your-project-name> |
| GitHub username / org | <your-github-username> |
| Initial version | 0.1.0 |
| Install dependencies? | Yes |
After answering, a summary is shown and the user can confirm or re-enter their choices.
Build & Development
The CLI is built with tsup and published independently from the monorepo:
| Script | Command |
|---|---|
build | tsup (bundles to dist/index.js) |
dev | tsup --watch |
start | node ./dist/index.js |
The CLI has its own version (vX.Y.Z) separate from the monorepo version. It's published to npm via the publish-cli.yml GitHub Actions workflow on new releases.