Basics of Building a Web Application Template

What Is a Template?

A template is a starting project containing the common infrastructure you repeatedly need.

Instead of starting every project from an empty directory:

Template

New project

Add application-specific code

The template should contain stable, reusable infrastructure, not application-specific features.

What Belongs in a Template?

For a TypeScript web application:

my-template/
├── src/
│   ├── routes/
│   ├── lib/
│   └── index.ts
├── public/
├── tests/
├── .gitignore
├── package.json
├── tsconfig.json
├── wrangler.jsonc
└── README.md

Common reusable pieces:

Do not include something merely because it might be useful.

Infrastructure vs Application

A useful rule:

The template provides the skeleton. The project provides the features.

For example:

Template:
  authentication
  validation
  database setup
  error handling
  /login
  /signup

Application:
  /dashboard
  /projects
  /leaderboard

The template should avoid domain-specific concepts.

Start With a Working Application

Do not begin by creating dozens of empty files.

First build a small working application:

request

router

handler

validation

database

response

Then identify what you repeatedly need and extract those parts into the template.

This gives you a template based on proven code rather than theoretical organization.

Keep It Small

A template should make starting a project easier.

If you regularly delete half of the template when starting a project, the template is too large.

Prefer:

small template
    +
application code

over:

huge template
    -
things you don't need

Use Sensible Defaults

A good template should work immediately:

pnpm install
pnpm dev

Use sensible defaults for:

Configuration vs Secrets

Templates should contain configuration structure, not secrets.

Good:

DATABASE_URL=
SESSION_SECRET=

Commit:

.env.example

Ignore:

.env

Never put real credentials into the template repository.

Establish Conventions

One major benefit of a template is consistency.

For example:

src/
├── routes/
├── components/
├── lib/
├── db/
├── validation/
└── types/

Decide these conventions once instead of reconsidering them for every project.

Keep Dependencies Intentional

Every dependency in the template becomes a dependency in every project created from it.

Therefore:

dependency

maintenance cost

security/update burden

Only include dependencies that provide significant value.

Project Initialization

Some values should change for every new project:

project name
package name
database name
deployment name
README title
environment configuration

Initially, changing these manually is fine.

Later, you can build a generator:

create-my-app my-project

It can:

  1. Copy the template.
  2. Replace placeholders.
  3. Install dependencies.
  4. Initialize Git.
  5. Create environment files.
  6. Print next steps.

Git Strategy

Keep the template as its own repository:

web-template/

project-a
project-b
project-c

The template is the starting point for projects, not necessarily something that should automatically control them afterward.

Version the Template

Templates evolve:

v1
v2
v3

A new project can use the newest version while existing projects remain stable.

This is especially useful when infrastructure changes significantly.

What Not to Template

Avoid putting these into the base template:

Mental Model

Think of the template as your personal application operating system.

It provides:

structure
+ conventions
+ infrastructure
+ tooling
+ security defaults

The actual project provides:

business logic
+ domain models
+ pages
+ features

The goal is not to avoid writing code.

The goal is to avoid repeatedly writing the same code.