Skip to content
Public template

About

A modern static-site starter kit built on Gulp 5, Tailwind CSS 4, PostCSS and Browsersync — with HTML partials, live reload and an optimized production build.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Repository files navigation

Gulp Starter Pack

A small, readable static-site pipeline — HTML partials, Tailwind CSS 4, live reload, and a production build that actually works.

CI License: MIT Node Gulp Tailwind CSS


Not every site needs a framework. This is the build layer for the ones that don't: write plain HTML with reusable partials, style it with Tailwind, and get a minified, optimized dist/ folder you can drop on any host.

  • HTML partials — @@include('./partials/header.html'), no templating language to learn
  • Tailwind CSS 4 — configured in CSS, no tailwind.config.js
  • Live reload — Browsersync reloads on save, and injects CSS without a refresh
  • Real production build — minified CSS and JS, images re-encoded with sharp
  • Zero runtime dependencies — output is plain HTML, CSS, JS and images

Quick start

git clone https://github.com/rahmanow/gulp-starter-pack.git my-site
cd my-site
npm install
npm run dev

Then open http://localhost:9050. Edit anything in src/ and the browser updates itself.

Requires Node.js 20.19+, 22.13+ or 24+. Run nvm use to pick up the version in .nvmrc.

Using this as a template? Click Use this template on GitHub, or delete the git history and start fresh:

rm -rf .git && git init

Commands

Command What it does
npm run dev Build to .tmp/, serve on port 9050, watch and live-reload
npm run build Optimized production build into dist/
npm run zip Build, then archive it to release/gulp-starter-pack-<version>.zip
npm run deploy Build, then publish to surge.sh (needs configuring)
npm run clean Delete .tmp/, dist/ and release/
npm run lint ESLint over the build config and src/js/
npm run format Format everything with Prettier
npm run check Lint + format check + build — the same suite CI runs

Every script maps to a Gulp task, so npx gulp build works too.

Project structure

src/                    Everything you edit
├── index.html          A page. Add more alongside it.
├── partials/           Fragments pulled in with @@include — never emitted
│   ├── header.html
│   └── footer.html
├── css/
│   └── main.css        Tailwind entry point and design tokens
├── js/
│   ├── main.js         Your code — bundled into js/main.js
│   ├── libs/           Bundled first, ahead of your code
│   └── vendor/         Copied verbatim, never bundled or minified
└── img/                Optimized during production builds

config.js               Paths, dev-server port, deploy target
gulpfile.js             The pipeline itself

.tmp/                   Development output (gitignored, scratch)
dist/                   Production output (gitignored)
release/                Zipped builds (gitignored)

.tmp/ is the fast, unminified development build that Browsersync serves. It is scratch space, which is why it is hidden — you never deploy it. dist/ is the optimized build you ship. Both are regenerated from scratch, so never edit them directly.

How it works

Pages and partials

Any .html file in src/ becomes a page. Anything in src/partials/ is a fragment: it is included into pages but never emitted on its own.

@@include('./partials/header.html')

<h1>Hello</h1>

@@include('./partials/footer.html')

Includes can pass data, which is handy for per-page titles:

@@include('./partials/header.html', { "title": "About us" })

Then in the partial, @@title is substituted. See gulp-file-include for the full syntax.

Styling

Tailwind CSS 4 is configured in CSS, not JavaScript. Open src/css/main.css:

@import "tailwindcss" source(none);

@source "../*.html";
@source "../partials/**/*.html";
@source "../js/**/*.js";

@theme {
  --color-brand-500: oklch(0.68 0.16 155);
  --radius-card: 0.875rem;
}

Tokens in @theme become utilities automatically — --color-brand-500 gives you bg-brand-500, text-brand-500, border-brand-500, and --radius-card gives you rounded-card. There is no config file to keep in sync.

source(none) turns off automatic file scanning so the build never walks node_modules/ or your own output. The trade-off is that new template folders need an @source line, or their classes will not be generated.

Reusable component classes go in @layer components:

@layer components {
  .btn {
    @apply rounded-card bg-brand-500 px-4 py-2 font-medium text-white;
  }
}

Coming from 1.x? Sass has been removed — Tailwind 4 is built to replace preprocessors and advises against pairing the two. Nesting and @apply still work; see CHANGELOG.md to migrate.

JavaScript

Files in src/js/libs/ are concatenated first, then everything directly in src/js/, producing a single minified js/main.js.

Anything in src/js/vendor/ is copied through untouched — use it for pre-built libraries you want to load with their own <script> tag.

There is no Babel step. Output targets modern browsers, which is the same baseline Tailwind 4 requires (Safari 16.4+, Chrome 111+, Firefox 128+).

Images

Development copies images as-is to keep the watch loop fast. Production re-encodes them with sharp — the sample cover image drops by about 86%. Anything sharp cannot process (SVG, video) passes through untouched instead of failing the build.

Configuration

Everything lives in config.js:

export default {
  port: 9050, // dev server port
  open: false, // open a browser on start
  src: "./src",
  dev: "./.tmp", // development output (scratch)
  dist: "./dist", // production output
  surgeDomain: "", // set to enable `npm run deploy`
  // ...paths and image options
};

Adding a folder of templates? Add its glob to paths.html and an @source line in src/css/main.css, so Tailwind sees the classes you use there.

Deploying

dist/ is a static folder — host it anywhere.

GitHub Pages is already wired up. Enable it under Settings → Pages → Source: GitHub Actions and every push to master publishes automatically via .github/workflows/pages.yml.

Netlify / Vercel — build command npm run build, publish directory dist.

Cloudflare Workers — add a wrangler.jsonc pointing at the build output, then run npx wrangler deploy:

{
  "name": "gulp-starter-pack",
  "compatibility_date": "2026-08-28",
  "assets": { "directory": "./dist" }
}

A purely static site needs no Worker script — just the assets block. Cloudflare recommends Workers over Pages for new projects; Pages still works, but new features are going to Workers.

surge.sh — set your domain in config.js, then npm run deploy:

surgeDomain: "my-site.surge.sh",

It refuses to run while that is empty rather than guessing a target.

Contributing

Issues and pull requests are welcome — see CONTRIBUTING.md. Run npm run check before opening a PR; it runs exactly what CI runs.

Working with an AI assistant? AGENTS.md documents the repo's conventions and invariants in a form agents can follow.

License

MIT © Azat Rahmanov

About

A modern static-site starter kit built on Gulp 5, Tailwind CSS 4, PostCSS and Browsersync — with HTML partials, live reload and an optimized production build.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Contributors

Languages