Create web
Scaffold a production-ready web application from language templates. Use when the user wants to bootstrap a new web project from scratch.From its SKILL.md
npx -y skills add pavelsimo/skills --skill create-webAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
10.9 KB, ~2.6k tokens by cl100k_base, as published. Nobody here has run it
create-web skill
features
- Scaffolds a complete, production-ready web application from a language template
- Ruby on Rails 8.x template built on 37signals conventions (Basecamp / Fizzy architecture)
- Python template: Reflex (pure-Python UI) + FastAPI mounted via
api_transformer, SQLite with WAL mode, SQLModel + Alembic migrations - Passwordless magic link authentication in both templates — no Devise, no auth library
- Ruby: UUID primary keys, Solid Queue/Cache/Cable (no Redis), Hotwire + importmap-rails, native CSS with cascade layers, Minitest + fixtures
- Python: uv + ruff + mypy strict + pytest with coverage gate, lefthook pre-commit hooks
- Kamal deployment configuration with multi-stage Dockerfile (both templates)
- GitHub Actions CI + automatic Kamal deploy on push to main
- Comprehensive
AGENTS.mdencoding 37signals engineering principles (symlinked asCLAUDE.md)
usage
/create-web
/create-web name=my-app template=ruby database=mysql
/create-web name=my-app template=python
workflow
Read templates/ to understand the available templates and what variable placeholders each one uses before collecting any input from the user. Read reference/37signals-style.md before changing Rails conventions, and reference/template-maintenance.md only when adding a new language template.
1. clarify
Collect these values via AskUserQuestion. Auto-detect github_user silently; never prompt the user for it.
| Field | Default | Notes |
|---|---|---|
name | — | Lowercase, hyphenated app name (e.g., my-app) |
template | ruby | ruby or python |
description | — | One sentence: what this app does |
github_user | auto | gh api user --jq .login |
database | sqlite | (ruby only) sqlite or mysql — python is always SQLite with WAL |
ruby_version | 3.4.2 | (ruby only) Latest stable Ruby |
python_version | 3.13 | (python only) Latest stable Python |
visibility | private | private or public |
Derived values — never ask the user:
| Variable | Derivation | Example |
|---|---|---|
APP_CLASS | PascalCase(name) | my-app → MyApp |
APP_MODULE | underscore(name) | my-app → my_app |
APP_NAME_HUMAN | Title Case(name) | my-app → My App |
YEAR | current year | 2025 |
PascalCase: split on -, capitalize each word, join. Underscore: replace - with _.
APP_CLASS is used by the ruby template only.
2. show spec card
Display a confirmation card before creating anything.
For template=ruby:
╭─ App Spec ──────────────────────────────────────────╮
│ Name: {name} │
│ Class: {APP_CLASS} │
│ Description: {description} │
│ Template: Ruby on Rails 8.x (37signals style) │
│ Database: {database} │
│ Ruby: {ruby_version} │
│ Auth: Passwordless magic links (no Devise) │
│ Frontend: Hotwire (Turbo + Stimulus) + importmap │
│ CSS: Native CSS (no Tailwind) │
│ Jobs: Solid Queue (no Redis) │
│ Deploy: Kamal │
│ Repo: github.com/{github_user}/{name} │
╰──────────────────────────────────────────────────────╯
For template=python:
╭─ App Spec ──────────────────────────────────────────╮
│ Name: {name} │
│ Module: {APP_MODULE} │
│ Description: {description} │
│ Template: Python + Reflex (37signals style) │
│ Database: SQLite (WAL mode) │
│ Python: {python_version} │
│ Auth: Passwordless magic links │
│ Frontend: Reflex (pure-Python, compiles to React) │
│ API: FastAPI via api_transformer │
│ Tooling: uv · ruff · mypy · pytest · lefthook │
│ Deploy: Kamal │
│ Repo: github.com/{github_user}/{name} │
╰──────────────────────────────────────────────────────╯
Ask: "Does this look right? Shall I scaffold the project?"
3. scaffold
Execute in order. Steps 1, 6, 7, and 8 are identical for both templates; steps 2–5 branch on the template.
-
Create GitHub repo and clone:
gh repo create {github_user}/{name} --{visibility} --clone --description "{description}" cd {name} -
Copy template files with variable substitution:
- Copy all files from
templates/{template}/(relative to this skill's directory) to the project root - Substitute all
{{PLACEHOLDER}}tokens in both file contents and filenames:{{APP_NAME}}→{name}{{APP_MODULE}}→{APP_MODULE}{{APP_NAME_HUMAN}}→{APP_NAME_HUMAN}{{GITHUB_USER}}→{github_user}{{DESCRIPTION}}→{description}{{YEAR}}→ current year- ruby only:
{{APP_CLASS}}→{APP_CLASS},{{RUBY_VERSION}}→{ruby_version},{{DATABASE}}→{database}(value:sqlite3for sqlite,mysql2for mysql) - python only:
{{PYTHON_VERSION}}→{python_version}
- Strip
.tmplextension from all*.tmplfiles after substitution - Make all bin scripts executable:
chmod +x bin/*
- Copy all files from
-
Install dependencies:
- ruby:
bundle install - python (also generates
uv.lock, which must be committed):uv sync --dev
- ruby:
-
Prepare database:
- ruby (runs db:create + db:migrate + db:seed):
bin/rails db:prepare - python (generate the initial migration, apply it, seed):
uv run alembic revision --autogenerate -m "create auth tables" uv run alembic upgrade head uv run python -m {APP_MODULE}.seed
- ruby (runs db:create + db:migrate + db:seed):
-
Install git hooks:
- ruby:
bundle exec lefthook install - python:
uv run lefthook install
- ruby:
-
Create CLAUDE.md symlink:
ln -s AGENTS.md CLAUDE.md -
Initial commit and push:
git add -A git commit -m "🎉 init: scaffold {APP_NAME_HUMAN} from create-web" git push -u origin main -
Configure GitHub repo:
gh repo edit --enable-wiki=false --enable-issues=true
4. output summary
For template=ruby:
✅ Created: https://github.com/{github_user}/{name}
Template: Ruby on Rails 8.x (37signals style)
Next steps:
cd {name}
bin/dev # start development server (localhost:3000)
open http://localhost:3000 # view the app
bin/rails test # run tests
make lint # run rubocop
bin/rails generate model ... # add your first model
Documentation:
docs/development.md # local setup guide
docs/deployment.md # Kamal deployment guide
config/deploy.yml # Kamal deployment config — fill in your server IP and domain
AGENTS.md # AI agent conventions (← CLAUDE.md)
For template=python:
✅ Created: https://github.com/{github_user}/{name}
Template: Python + Reflex (37signals style)
Next steps:
cd {name}
make dev # start development server (localhost:3000)
open http://localhost:3000 # view the app
make test # run tests
make ci # format check + lint + tests
make db-makemigrations m="..." # generate a migration after adding models
Documentation:
docs/development.md # local setup guide
docs/deployment.md # Kamal deployment guide
config/deploy.yml # Kamal deployment config — fill in your server IP, domain, and API_URL
AGENTS.md # AI agent conventions (← CLAUDE.md)
template variable reference
| Placeholder | Example | Used in |
|---|---|---|
{{APP_NAME}} | my-app | filenames, Kamal config, README |
{{APP_CLASS}} | MyApp | (ruby only) Ruby module names, application.rb |
{{APP_MODULE}} | my_app | database names, directory paths, Python package |
{{APP_NAME_HUMAN}} | My App | page titles, email subjects, commit message |
{{GITHUB_USER}} | pavelsimo | repo URL, Docker image registry, Kamal |
{{DESCRIPTION}} | A task manager... | README, repo description |
{{RUBY_VERSION}} | 3.4.2 | (ruby only) .ruby-version, Gemfile, Dockerfile |
{{DATABASE}} | sqlite3 | (ruby only) database.yml default adapter |
{{PYTHON_VERSION}} | 3.13 | (python only) .python-version, pyproject.toml, Dockerfile |
{{YEAR}} | current year | README license line |
Substitution applies to both file contents and filenames. .tmpl extension is stripped post-substitution.
best practices
- Always show the spec card and wait for explicit confirmation before creating the GitHub repo or any files
- Detect
github_usersilently viagh api user --jq .login; never prompt the user for it - Both templates ship with a working auth system — do not replace it with Devise or other auth libraries
- When modeling state ("close", "archive", "publish"), always use a separate record (
Closure,Publication) rather than boolean columns — this is the 37signals pattern
Ruby:
- When users ask for tests, remind them that fixtures (not FactoryBot) and Minitest (not RSpec) are the 37signals convention
- CSS additions go in focused component files under
app/assets/stylesheets/using cascade layers — never suggest Tailwind - Background jobs go through Solid Queue — never suggest Sidekiq or Redis
- New routes nominalize verbs: "close" →
resource :closure, "pin" →resource :pin, "watch" →resource :watch
Python:
- Domain logic goes in plain functions taking a
sqlmodel.Session(likeauth.py) — never in Reflex state or service classes - Migrations only via
make db-makemigrations+make db-migrate(Alembic) — never edit the schema by hand - Use native Reflex components — never suggest custom React components or a JavaScript frontend
- The app runs a single backend worker; never suggest Redis, Celery, or PostgreSQL for a single-server deployment
What ships with it: 162 files
154.0 KB alongside SKILL.md, 32 of them executable
reference/
- 37signals-style.md751 B
- template-maintenance.md1.0 KB
templates/
- python/AGENTS.md.tmpl6.9 KB
- python/alembic/env.py.tmpl959 B
- python/alembic.ini886 B
- python/alembic/script.py.mako638 B
- python/alembic/versions/.keep0 B
- python/{{APP_MODULE}}/api.py.tmpl266 B
- python/{{APP_MODULE}}/{{APP_MODULE}}.py.tmpl247 B
- python/{{APP_MODULE}}/auth.pyruns3.0 KB
- python/{{APP_MODULE}}/db.py.tmpl867 B
- python/{{APP_MODULE}}/__init__.pyruns0 B
- python/{{APP_MODULE}}/mailer.py.tmpl1.0 KB
- python/{{APP_MODULE}}/models.pyruns1.7 KB
- python/{{APP_MODULE}}/pages/index.py.tmpl595 B
- python/{{APP_MODULE}}/pages/__init__.pyruns51 B
- python/{{APP_MODULE}}/pages/sign_in.py.tmpl945 B
- python/{{APP_MODULE}}/pages/verify.pyruns998 B
- python/{{APP_MODULE}}/seed.pyruns855 B
- python/{{APP_MODULE}}/settings.pyruns311 B
- python/{{APP_MODULE}}/state.pyruns2.1 KB
- python/assets/favicon.ico1.1 KB
- python/bin/docker-entrypointruns266 B
- python/Caddyfile203 B
- python/config/deploy.yml.tmpl1.4 KB
- python/Dockerfile.tmpl1.6 KB
- python/.dockerignore167 B
- python/docs/deployment.md.tmpl4.3 KB
- python/docs/development.md.tmpl3.6 KB
- python/.gitignore226 B
- python/.kamal/secrets248 B
- python/.lefthook.yml145 B
- python/Makefile.tmpl944 B
- python/pyproject.toml.tmpl1.1 KB
- python/.python-version.tmpl19 B
- python/README.md.tmpl1.4 KB
- CHANGELOG.md1.3 KB
- LICENSE1.0 KB
- .markdownlint.json76 B
- README.md2.2 KB
122 more files not listed here. See all 162 in the repository.