@mariozechner/create-app
Version:
Project scaffolding for TypeScript applications and libraries
308 lines (236 loc) • 8.89 kB
Markdown
# Create App
CLI for creating deployable web applications with Docker, Caddy, and modern tooling.
## Why This Exists
Self-hosting web applications shouldn't require complex infrastructure. This CLI creates apps that deploy to a single server with automatic SSL and dev/prod parity - simple, reliable hosting on your own or rented hardware.
Perfect for:
- **Personal projects** - blogs, portfolios, side projects
- **Small businesses** - company websites, internal tools
- **Prototypes** - MVPs that need real deployment
- **Learning** - because it's fun to run your own infra stack
Not suitable for:
- **High-scale applications** (use Kubernetes/cloud platforms)
- **Multi-region deployments** (single server architecture)
- **Complex microservices** (better served by orchestration platforms)
## Quick Start
### Interactive Setup
```bash
# Create a new app (prompts for template and configuration)
npx @mariozechner/create-app my-app
cd my-app
# Start development server
./run.sh dev
# Deploy to your server (see Server section below)
./run.sh deploy
```
### CLI Arguments (No Prompts)
```bash
# Create with all options specified
npx @mariozechner/create-app my-app \
--template spa-api \
--domain myapp.com \
--server myserver.hetzner.de \
--serverDir /home/username
# Quick static site
npx @mariozechner/create-app my-blog --template static --domain blog.example.com
# See all options
npx @mariozechner/create-app --help
```
## Templates
### Available Templates
#### Static
- **Description**: Static file server with modern frontend tooling
- **Features**:
- Tailwind CSS 4 with live reload
- TypeScript support
- Automated testing setup
- Optimized production builds
- **Use for**: Landing pages, documentation sites, blogs, portfolios
#### SPA + API
- **Description**: Single Page Application with backend API
- **Inherits**: All features from the Static template
- **Additional Features**:
- Express.js backend API
- Frontend/backend code sharing
- API proxy in development
- Separate frontend/backend builds
- **Use for**: Web apps, internal tools, data-driven applications
#### Web Library
- **Description**: TypeScript library for the browser
- **Features**:
- ESM output with source maps
- TypeScript declarations
- Hot-reload development server with @mariozechner/hotserve
- Prettier formatting + Biome linting
- Publishing script included
- **Use for**: Browser libraries, web components, frontend utilities
#### Node Library
- **Description**: TypeScript library for Node.js with CLI support
- **Features**:
- ESM output with TypeScript declarations
- CLI executable support
- Prettier formatting + Biome linting
- Publishing script included
- **Use for**: Node.js libraries, CLI tools, backend utilities
## Prerequisites
### Server Setup
Your production server needs Docker, Caddy, and proper configuration. See [SERVER.md](SERVER.md) for complete setup instructions.
### DNS Configuration
Point your domain to the server:
```
A yourdomain.com -> server-ip
A *.yourdomain.com -> server-ip (for subdomains)
```
## Usage
### CLI Options
| Option | Short | Description | Example |
|--------|-------|-------------|---------|
| `--template` | `-t` | Template to use | `--template spa-api` |
| `--domain` | | Domain for the app | `--domain myapp.com` |
| `--server` | | Production server hostname | `--server myserver.com` |
| `--serverDir` | | Server directory path | `--serverDir /home/username` |
| `--frontendPort` | | Frontend development port | `--frontendPort 3000` |
| `--apiPort` | | API development port | `--apiPort 8000` |
| `--help` | `-h` | Show help message | `--help` |
**Available templates:** `static`, `spa-api`, `web-library`, `node-library`
### Template-Specific Instructions
After creating a project, check the generated `README.md` for detailed instructions specific to your template.
```bash
npx @mariozechner/create-app my-blog
cd my-blog
cat README.md # Template-specific instructions
```
## Development
### Working on the CLI
To work on this CLI tool itself:
```bash
git clone https://github.com/badlogic/create-app
cd create-app
npm install
npx tsx src/cli.ts test-app
```
### Template System
The template system supports inheritance and file transformations, making it easy to create and maintain templates.
#### Template Structure
Each template is a directory in `templates/` containing:
- `template.json` - Template metadata and configuration
- Template files and directories
- Special filename prefixes for transformations:
- `+filename` - File will be merged with inherited file (JSON/YAML only)
- `-filename` - Marks a file/directory for deletion from inherited template
- Regular files - Replace inherited files or create new ones
#### Creating a New Template
1. Create a new directory in `templates/`:
```bash
mkdir templates/my-template
```
2. Add `template.json`:
```json
{
"name": "My Template",
"description": "Description of what this template creates",
"prompts": [
{
"name": "domain",
"type": "text",
"message": "Domain (e.g. myapp.com)"
}
]
}
```
3. Add your template files with proper structure:
```
templates/my-template/
├── template.json
├── package.json
├── src/
│ └── index.ts
└── infra/
├── Caddyfile
└── docker-compose.yml
```
#### Template Inheritance
Templates can inherit from other templates using the `inherits` field:
```json
{
"name": "Extended Template",
"description": "Builds on the static template",
"inherits": ["static"],
"prompts": [...]
}
```
**Inheritance rules:**
- Files from parent templates are copied first
- Child template files override parent files with the same path
- Files prefixed with `+` are merged with parent files (JSON/YAML only)
- Files prefixed with `-` delete the corresponding file from parent
- Multiple inheritance is processed in order
**Example:** The `spa-api` template inherits from `static` and:
- Keeps all static template files (frontend build, testing, etc.)
- Adds `+package.json` to merge additional dependencies
- Adds `+docker-compose.yml` to extend Docker services
- Adds new files like `src/backend/server.ts`
- Could use `-README.md` to remove the parent's README (if needed)
#### File Merging
Files prefixed with `+` are intelligently merged based on their type:
- **JSON files** (`+package.json`): Deep merged with parent
- **YAML files** (`+docker-compose.yml`): Deep merged with special handling for arrays
- **Other files**: Not supported for merging (warning shown)
Example `+package.json` in child template:
```json
{
"scripts": {
"build:backend": "tsup"
},
"dependencies": {
"express": "^4.18.0"
}
}
```
This will merge with the parent's package.json, adding new scripts and dependencies.
#### File Deletion
Files or directories prefixed with `-` mark items for deletion from the inherited template:
- `-README.md` - Removes README.md from parent template
- `-src/oldfeature/` - Removes entire directory from parent template
This is useful when inheriting from a template but needing to remove specific files.
#### Variable Substitution
Template files can use variables that get replaced during project creation:
- `{{projectName}}` - The project name
- `{{domain}}` - The domain from prompts
- `{{server}}` - The server hostname
- `{{serverDir}}` - The server directory
- Any other prompt values
### Best Practices
1. **Use inheritance** to avoid duplication - build on existing templates
2. **Keep templates focused** - each template should solve one use case well
3. **Document your template** - include a README.md in the template
4. **Test thoroughly** - ensure both dev and production modes work
5. **Follow conventions** - match the structure and patterns of existing templates
## Common Issues
**Server setup required:**
Before deploying, your server needs Docker and Caddy configured. See [SERVER.md](SERVER.md) for complete setup instructions.
**Template-specific issues:**
Check the `README.md` in your generated project for troubleshooting specific to your template type.
## Publishing
The `publish.sh` script handles versioning, tagging, and publishing to npm:
```bash
# Patch release (1.0.0 -> 1.0.1)
./publish.sh
# Minor release (1.0.1 -> 1.1.0)
./publish.sh minor
# Major release (1.1.0 -> 2.0.0)
./publish.sh major
```
The script will:
1. Check for uncommitted changes
2. Run checks (format, lint, type-check)
3. Build the project
4. Bump version in package.json
5. Commit and tag the version
6. Push to GitHub with tags
7. Publish to npm
## Contributing
Contributions are welcome! When adding new templates:
1. Follow the template structure guidelines above
2. Include comprehensive documentation
3. Test both development and production workflows
4. Consider if inheritance from existing templates makes sense