# OptimizedHTML 5: a Gulp starter that bundles SSI, four CSS preprocessors and deploy by rsync

> OptimizedHTML 5 is a small Gulp based front end starter from WebDesign Master that ships a fixed app and dist layout, optional Sass, Less or Stylus, Bootstrap Reboot, server side HTML includes through Browsersync, and an rsync deploy task. It suits static brochure style sites that want a sane build, and it is tied to Gulp, SSI and Apache conventions.

**wdmcourses/OptimizedHTML-5** — OptimizedHTML 5 – Lightweight production-ready Gulp starter.

- Repository: https://github.com/wdmcourses/OptimizedHTML-5
- Website: https://webdesign-master.ru/blog/tools/optimizedhtml-5.html
- Stars: 562 · Forks: 239
- Language: JavaScript
- License: not declared
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/wdmcourses-optimizedhtml-5

## A starter for static sites that fixes the folder layout

OptimizedHTML 5 is described as a lightweight production ready Gulp starter, and the value of a starter is entirely in the decisions it makes for you. This one makes a lot of them, and makes them visibly.

The repository root is short: a .bowerrc, a .gitignore, an app directory, a dist directory, a gulpfile.js, a package.json and the readme. The manifest declares the package as optimizedhtml at version 5.1.0, with the type field set to module, so the gulpfile is an ES module rather than CommonJS. There are exactly two npm scripts, dev and build, and they map onto gulp tasks.

```json
  "scripts": {
    "dev": "gulp",
    "build": "gulp build"
  },
```

The dependency list is where the design decisions become visible. Gulp 5 is the task runner, and the pipeline is assembled from small plugins: browser-sync with browsersync-ssi for the local server, gulp-sass with gulp-sass-glob, gulp-less with gulp-less-glob, and gulp-stylus for the three preprocessor options, plus gulp-postcss with autoprefixer, cssnano for minification, webpack with webpack-stream and terser-webpack-plugin for the JavaScript, and a set of imagemin packages for images. gulp-rsync handles the deploy, del clears output directories, and gulp-concat and gulp-noop round out the list.

That is a substantial pipeline for something calling itself lightweight, but the weight is in the plugin count rather than in any one heavy framework. The scripts and styles are bundled through webpack, which is the one part that suggests a build complexity beyond a simple concatenation.

The browserslist field is set to the last 10 versions, which is what autoprefixer and Babel read to decide which prefixes and transforms to emit. A starter that fixes this for you removes a common source of build differences between machines.

## Four preprocessor choices behind one option

The gulpfile exposes two options, and the first is the preprocessor. The documentation lists sass, less and styl as the optional values, and it adds a specific note: sass also works with the Scss syntax in the styles/sass/blocks import folder.

That is the design in miniature. You pick one preprocessor for a project, put the main file in app/styles/{preprocessor}/main, and drop the partials into app/styles/{preprocessor}/blocks, where any number of files can sit in any order and they are pulled in automatically by the glob plugin. A Sass project and a Less project have the same shape on disk, which means switching preprocessors later means renaming files and rewriting syntax, not restructuring the project.

The second option is fileswatch, a list of file extensions to watch for a hard reload. This matters more than it looks, because with preprocessors the extension of a partial does not tell you which preprocessor owns it. A Sass partial called _config.scss and a Less partial called _config.less live in sibling folders, and the watch list is how you tell the watcher which directories to care about.

The styles configuration follows the same pattern. The project styles config is placed in app/styles/{preprocessor}/_config, so the same placeholder name works for all three preprocessors. Global variables, breakpoints and colours live in one file per project rather than being spread across every partial.

The two documentation-only points worth noting: the compiled CSS lands in app/css/main.min.css rather than next to the source, and the source script lives in app/js/app.js with its minified counterpart in app/js/app.min.js. The dist directory is the sibling of app, so a reviewer can see source and output side by side.

## Server side includes let you compose pages in the browser

The most distinctive feature of this starter is that it does not need a template engine. HTML is composed with server side includes, served by the Browsersync server through the browsersync-ssi plugin.

Any part of a page can be imported with a construct in any of the HTML files, pointing at a file under a parts directory, and the include works in the local development server. Variables work too, using a set directive to assign a value and an echo directive to read it back, so a title can be defined in one file and printed inside a shared header partial.

This is a deliberate design choice with a specific appeal. There is no template syntax to collide with the HTML, no template engine to configure, and the files you write are the files you deploy. For a site with a common header, footer and navigation across a dozen pages, that removes a whole layer.

The cost is that the mechanism only exists in the development server. Once the site is deployed, those includes have to be resolved by the web server, which means Apache with mod_include enabled, and the deployed output is only correct if the server processes them. On a host that serves static files only, the includes will not be resolved, and a page that looked right in development will show the raw include comment in production. That is a deployment coupling worth knowing before you commit to the approach.

The same dependency explains the other choice in the starter. The caching rules ship as .htaccess code, and .htaccess is an Apache convention, so the whole project is oriented towards Apache hosting rather than a platform agnostic static host.

## Gulp tasks for build, assets and rsync deploy

The task list is short enough to learn in a minute, and it maps onto a normal working rhythm.

The default gulp task runs scripts, images, styles, browsersync and startwatch, so a bare gulp invocation starts the local server, compiles everything and begins watching. The asset tasks are scripts, styles, images and assets, where assets means all of them together, and each produces the corresponding output. There is a build task for the project build and a deploy task for project deployment via Rsync.

That is the whole interface: watch during development, build for output, deploy to a server. The deploy task is worth a second look because it is the one place where a starter hands you a credential-bearing operation. gulp-rsync copies the dist directory to a remote host, which means the connection details and any SSH key or password live in the gulpfile. That file is in the repository, and the readme does not document a way to keep those credentials out of it or to point at an environment variable instead. If you use the deploy task, check what the gulpfile contains and what your .gitignore excludes before the first push.

The image pipeline is the other part worth naming. The imagemin family is present, with imagemin-mozjpeg for JPEG, imagemin-pngquant for PNG and imagemin-svgo for SVG, and source images are placed in app/images/src while the compressed ones land in app/images/dist. Compression is therefore part of the normal build rather than a separate step you remember to run before deploying.

One known issue is documented. A long preprocessor compile is fixed by disabling the safe write option in PHPStorm or WebStorm settings, which is the usual cause of a file watcher stalling on save in those editors.

## The .htaccess file handles caching, not the build

Caching is handled entirely on the server side, and the starter hands you a complete .htaccess snippet to paste into the root of the site.

```apache
AddType application/font-woff2 .woff2
AddType image/svg+xml .svg

ExpiresActive On
ExpiresDefault "access plus 5 seconds"

# Cache Images
ExpiresByType image/x-icon "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
ExpiresByType image/svg+xml "access plus 2592000 seconds"

# Cache Fonts
ExpiresByType application/font-woff2 "access plus 2592000 seconds"

# Cache other content types (CSS, JS, HTML, XML)
ExpiresByType text/css "access plus 604800 seconds"
ExpiresByType text/javascript "access plus 2592000 seconds"
ExpiresByType text/html "access plus 600 seconds"
```

The shape is sensible. Images and fonts get a 2592000 second expiry, which is thirty days, CSS gets a week, and HTML gets ten minutes, with a fallback of five seconds for anything unmatched. The two AddType lines at the top fix the content type for woff2 fonts and SVG files, which servers frequently mislabel, and a mislabelled font is a download that the browser refuses to use.

The snippet is also wrapped in ifModule guards in the full version, with mod_expires for the caching rules and mod_deflate for compression, and the deflate rule lists the content types to compress, including the woff2 and svg types. The guarded form matters on shared hosting, where a module may not be loaded, and an unguarded directive produces a 500 rather than a missing feature.

Two things the readme does not do. It does not explain how to translate these rules to an nginx server, and it does not mention cache busting for the HTML and CSS files themselves. Since CSS is cached for a week and HTML for ten minutes, a deploy that changes a stylesheet will not reach a returning visitor for a week unless the file name or a query string changes. The starter does not include a hashing step in the build, so that is something you add yourself.

The included features are modest by design: bootstrap-reboot, a Bootstrap Reboot CSS collection, and bootstrap-grid as an optional grid collection. Both are pinned to Bootstrap 5.3, which matches the bootstrap entry in the dependency list. Reboot normalises element styling so your own CSS starts from a predictable baseline, and the grid is optional, so the starter does not force a grid system on you.

## Where a Gulp starter from 2026 stops being the answer

The honest framing is that this is a small static site starter with a specific set of conventions, and several of those conventions are now dated.

The first issue is the toolchain age. Gulp 5 is current, but the starter assembles its build from around forty individual plugins rather than from a framework with a single configuration object. That means the dependency list is long, the install is slow, and each plugin is a separate thing that can break when its own dependencies move. The webpack inside the Gulp pipeline, used through webpack-stream and terser-webpack-plugin, is a second build tool nested in the first, which is the shape of pipeline that gets painful to debug.

The second issue is the server side include dependency, discussed above, and the third is Apache. A modern static host or a CDN fronted deployment will not process SSI, and .htaccess is ignored by nginx and by most CDN edges. The starter is oriented towards a traditional LAMP host, and moving a site built this way to a static platform means reworking how pages are composed and how caching is configured, which is a migration rather than a config change.

The fourth issue is the fixed layout. The rules for src and dist paths are strict and specific, and they are documented as rules rather than as defaults. That is good for consistency and bad for a project with an unusual shape, and it means an existing project with its own conventions would have to be reshaped around the starter rather than the other way round.

The alternative to weigh against it is a modern bundler such as Vite with a static HTML template, where the dev server, the asset pipeline and the production build are one tool with one config, and where the same pages deploy to any static host. The trade is real: Vite gives you less out of the box for a purely static, non framework site, and you would write the HTML composition, the image compression and the cache headers yourself, which is exactly the work this starter has already done. The difference in approach is that OptimizedHTML 5 treats the page as a set of files composed by the server at request time, while a bundler based workflow treats the page as an artifact produced at build time.

On licensing, the repository is listed with an unknown licence, while the package manifest declares ISC for the npm package. That mismatch is worth resolving before you build commercial work on it, and any conclusion about what you may do with the code needs advice from someone qualified rather than a summary here. The last push was on 2026-07-15, and the repository publishes no GitHub releases, so there is no tagged version to pin and you are tracking the master branch.

## Conclusion

OptimizedHTML 5 suits a developer building a static site with a handful of pages who wants a working build, image compression and cache headers without assembling a toolchain, and it does not suit an application front end, a team standardising on Vite or webpack directly, or anyone deploying to a host without Apache, because the HTML includes rely on server side includes and the caching rules are written as .htaccess directives. Before you adopt it, read the layout rules in the readme, since the src and dist paths are fixed and every page you write has to match them, and check the licence yourself, because the repository is listed as unknown while the package manifest declares ISC.

## FAQ

### What is OptimizedHTML 5 and what does it include?

It is a lightweight Gulp starter for static sites that includes Sass, Less or Stylus preprocessors, cssnano, Browsersync, PostCSS with Autoprefixer, webpack-stream with Babel, Rsync deploy, gulp-imagemin, Bootstrap Reboot, server side HTML includes and a .htaccess file for resource caching.

### How do I install and run OptimizedHTML 5?

Clone or download the project from GitHub, install the node modules with npm i, then run npm run dev for the development server or npm run build for the production build. The readme also gives a single clone command that removes the repository's own files afterwards.

### Which CSS preprocessors does OptimizedHTML 5 support?

The preprocessor option accepts sass, less and styl, and the sass option also works with the Scss syntax in the styles/sass/blocks import folder. Partials in that blocks folder are included automatically into the main file in any order.

### How do I include parts of an HTML page in OptimizedHTML 5?

It uses server side includes served by the Browsersync server through the browsersync-ssi plugin, so any HTML file can import a part with an include construct pointing into a parts directory, and variables can be set and echoed the same way. The includes need to be processed by the web server after deployment.

### How does OptimizedHTML 5 handle caching and deploys?

Caching is handled by an .htaccess file with ExpiresByType rules for images, fonts, CSS, JS and HTML, and the deploy task uses Rsync through the gulp-rsync plugin to copy the project to a remote host. The readme does not document how to keep the rsync credentials out of the gulpfile.

## Sources

- [Issues](https://github.com/wdmcourses/OptimizedHTML-5/issues)
- [Project website](https://webdesign-master.ru/blog/tools/optimizedhtml-5.html)
- [README](https://github.com/wdmcourses/OptimizedHTML-5/blob/master/README.md)
- [wdmcourses/OptimizedHTML-5 on GitHub](https://github.com/wdmcourses/OptimizedHTML-5)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/wdmcourses-optimizedhtml-5
