Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Gulp Bootstrap

gulp-bootstrap

A minimal Gulp 4 + Bootstrap 5.3 starter for static site development.

Blank means no theme, not no tooling.

You get a working build pipeline: SCSS compilation, reusable HTML partials, image optimization, minification and live reload. Bootstrap supplies the UI components; this repo supplies the development environment around them.

No theme. No prebuilt pages. No design system. No third-party UI plugins.

Requirements

  • Node.js 20 or newer, and npm
  • Gulp 4.x — installed locally by npm install, no global install needed

Gulp 5 is not supported yet. It changes default stream encoding and enforces stricter async task completion. The pipeline plugins (gulp-imagemin, gulp-clean-css) have not been verified under Gulp 5. Do not upgrade the Gulp major version without testing the full build first.

Quick Start

git clone https://github.com/azwiki/gulp-bootstrap.git my-project
cd my-project
rm -rf .git
npm install
npm start

The browser opens automatically. Edit files in src/ — Gulp rebuilds and reloads on every change.

src/  →  Gulp  →  dist/
 ↑                  ↓
edit here        website

Always edit files in src/. dev/ and dist/ are generated on every build — never edit them by hand.

What You Get

  • Bootstrap 5.3, used as a prebuilt vendor package (copied from node_modules, not compiled from source)
  • Gulp 4 build pipeline
  • SCSS compilation with Autoprefixer
  • HTML includes / partials (gulp-file-include)
  • JavaScript copying
  • Image optimization (GIF, PNG, SVG; other formats are copied as-is)
  • CSS minification (clean-css) in production builds
  • BrowserSync live reload
  • Separate development and production builds
  • Favicon and web manifest support
  • No custom theme or visual design

Installation

Three equivalent ways — all produce the same project layout.

Option 1 — Git clone

Same as Quick Start. rm -rf .git disconnects the project from this repository; run git init afterwards to start your own history.

Option 2 — Download ZIP (no Git needed)

  1. On the GitHub page click Code → Download ZIP
  2. Unzip and open a terminal in the folder
  3. Run:
npm install
npm start

npm install is required first: it fetches Gulp, Bootstrap, Sass and the other tools listed in package.json. Use npm run build:dist instead of npm start if you only want a one-off build.

Option 3 — npm

mkdir my-project && cd my-project
npm install gulp-bootstrap

A postinstall script then:

  • copies gulpfile.js, src/, README.md and .gitignore into your project root (existing files are skipped, never overwritten);
  • merges the scripts and devDependencies from this package into your package.json;
  • removes the gulp-bootstrap entry from your dependencies.

Finish the setup:

rm -rf node_modules package-lock.json
npm install
npm start

The cleanup discards the temporary install (node_modules holds only the gulp-bootstrap package at that point, and the lockfile still references it). The second npm install fetches the real build tools: gulp, bootstrap, sass, and the rest.

Commands

npm install          # once, after cloning or changing package.json
npm start            # build:dist, then serve dist/ with BrowserSync live reload (Ctrl+C to stop)
npm run build:dev    # → dev/,  uncompressed, for debugging (not served, not watched)
npm run build:dist   # → dist/, minified, ready to deploy

dist/ is the finished static site — upload its contents to any static web server.

The watcher rebuilds pages, partials, SCSS, main.js, images (including the favicon) and root files. It does not watch gulpfile.js or the vendor copy tasks (Bootstrap, and any library you add) — restart npm start after changing those.

Project Structure

gulp-bootstrap/
├── gulpfile.js              # build logic
├── package.json
├── LICENSE
├── .gitignore
├── scripts/
│   └── postinstall.js       # used by the npm install method only
├── src/                     # you work here — everything else is generated
│   ├── index.html           # pages: any .html file, in src/ or its subfolders
│   ├── robots.txt
│   ├── site.webmanifest
│   ├── partials/            # reusable pieces (not built as pages)
│   │   ├── _head.html
│   │   ├── _navbar.html
│   │   ├── _footer.html
│   │   └── _scripts.html
│   └── assets/
│       ├── scss/main.scss   # your styles — empty by default
│       ├── js/main.js       # your JavaScript
│       └── img/
│           ├── favicon/             # favicon.png (linked from _head.html) + 192/256/512 px PNGs for site.webmanifest — replace with your own
│           └── screenshot.webp
├── dev/                     # generated by build:dev  (git-ignored)
└── dist/                    # generated by build:dist / npm start  (git-ignored)

clean:dev / clean:dist wipe the output directory before every build.

Adding a Page

Create src/about.html (any name, .html, not inside partials/):

<!doctype html>
<html lang="en">
<head>
@@include('_head.html', {
  "title": "About",
  "description": "About our website",
  "keywords": "about, bootstrap"
})
</head>
<body>
@@include('_navbar.html', { "siteName": "gulp-bootstrap" })

<main class="container py-5">
  <h1>About</h1>
  <p>Your page content goes here.</p>
</main>

@@include('_footer.html', { "siteName": "gulp-bootstrap" })
@@include('_scripts.html')
</body>
</html>

Gulp processes the includes and writes dist/about.html. Add the link to src/partials/_navbar.html.

Pages can also live in subfolders (src/blog/post.html → dist/blog/post.html). Use @@webRoot for every asset and page link so paths stay correct at any depth (see below).

HTML Partials

Repeated HTML lives in src/partials/. Change _navbar.html once and every page picks it up on the next build.

Values passed from a page are available in the partial as @@param:

<title>@@title</title>
<meta name="description" content="@@description">
<meta name="keywords" content="@@keywords">

@@webRoot is built into gulp-file-include: the relative path from the current page to the site root (. for index.html, .. for a page one folder deep). The bundled partials use it for all links:

<link rel="stylesheet" href="@@webRoot/assets/css/main.css">

gulp-file-include limitation: only flat @@param interpolation is reliable inside @@include(...). @@if / @@else can render as literal text. Keep partials free of conditional logic.

Styles, Scripts, Images

What Where Notes
Your styles src/assets/scss/main.scss Compiled to assets/css/main.css, loaded after bootstrap.min.css, so same-specificity rules override Bootstrap
Your JavaScript src/assets/js/main.js Copied as-is; kept separate from vendor code
Images src/assets/img/ GIF, PNG and SVG are optimized during the build; JPEG and WebP are copied unchanged
Favicon src/assets/img/favicon/favicon.png Replace with your own PNG; linked from _head.html and processed like any other image

Bootstrap itself is never modified:

Bootstrap  → vendor framework (node_modules)
main.scss  → your styles
main.js    → your JavaScript

Because Bootstrap's Sass is not compiled, Sass variables ($primary, etc.) cannot be customized. Override styles in main.scss or via --bs-* CSS variables.

Adding Dependencies

npm install <package>

Then make the library's files part of the build. Two options:

  • Ready-made .min.js / .min.css: reference them directly from a partial (or a CDN) — no Gulp changes needed.
  • Files from node_modules: add a copy task to gulpfile.js, as in the example below.

Example: adding GLightbox

1. Install

npm install glightbox

2. Add paths and copy tasks to gulpfile.js

Mirror the existing bootstrapjs:dev / bootstrapjs:dist tasks.

In the path object, add one entry to each of dev, dist and src:

dev:  { /* ... */ glightbox: 'dev/assets/vendor/glightbox/' },
dist: { /* ... */ glightbox: 'dist/assets/vendor/glightbox/' },
src:  { /* ... */ glightbox: [
  'node_modules/glightbox/dist/css/glightbox.min.css',
  'node_modules/glightbox/dist/js/glightbox.min.js'
] },

Add the tasks next to the Bootstrap ones:

/* GLightbox — copied as-is from node_modules */
gulp.task('glightbox:dev', function () {
  return gulp.src(path.src.glightbox).pipe(gulp.dest(path.dev.glightbox));
});
gulp.task('glightbox:dist', function () {
  return gulp.src(path.src.glightbox).pipe(gulp.dest(path.dist.glightbox));
});

Add them to the gulp.parallel(...) list of build:dev and build:dist:

gulp.parallel('html:dev', /* ... */ 'root:dev', 'glightbox:dev')
gulp.parallel('html:dist', /* ... */ 'root:dist', 'glightbox:dist')

Restart npm start — Gulp does not reload its own config.

3. Load the files in partials

src/partials/_head.html — after bootstrap.min.css:

<link rel="stylesheet" href="@@webRoot/assets/vendor/glightbox/glightbox.min.css">

src/partials/_scripts.html — before main.js:

<script src="@@webRoot/assets/vendor/glightbox/glightbox.min.js"></script>

4. Initialize in src/assets/js/main.js

// init lightbox for all links with class "glightbox"
GLightbox({ selector: '.glightbox' });

5. Use it in a page

<a href="@@webRoot/assets/img/photo.jpg" class="glightbox" data-gallery="gallery1">
  <img src="@@webRoot/assets/img/photo-thumb.jpg" alt="Photo" class="img-fluid">
</a>

Check that the files appear under dist/assets/vendor/glightbox/.

The starter intentionally ships no extra frontend libraries. Add only what your project needs.

Updating Dependencies

npm outdated                    # current / wanted (within package.json ranges) / latest
npm update                      # update everything within the ranges in package.json
npm update bootstrap            # update only Bootstrap (stays within ^5.3.3)
npm install bootstrap@latest    # jump to a new major version — read the release notes first
npm install bootstrap@5.3.3     # pin an exact version
npm update glightbox            # update a vendor library you added

After any update, run npm run build:dist and check the site in the browser.

Do not run npm install <package>@latest for gulp, del, gulp-imagemin or imagemin-pngquant. They are pinned with ~ on purpose. gulp@latest is Gulp 5, which is not supported; newer majors of del, gulp-imagemin and imagemin-pngquant are ESM-only and cannot be loaded by the require() calls in gulpfile.js. Plain npm update keeps them within their safe ranges.

Philosophy

Most frontend templates start with a full visual design and a pile of plugins, so a new site begins with deleting things. gulp-bootstrap goes the other way:

Bootstrap
+ build pipeline
+ HTML partials
+ empty project styles
+ empty project JavaScript

Then add only what the website actually requires.

License

MIT — see LICENSE.