Code Bytes
A small Gulp, Dart Sass and BrowserSync setup
Compile SCSS and refresh a loopback-only local preview with modern Gulp tasks and Dart Sass, without old Ruby Sass plugins.
Keep the local workflow small
For a plain HTML or PHP project, Gulp can still coordinate Sass compilation and browser refresh. The old Gulp 3 task arrays and Ruby Sass plugin below are historical. This version uses composed tasks and Dart Sass directly, with no global sudo installation.
If your project already has a working Vite, Astro or framework build, use its existing Sass integration instead of adding a second watcher.
Install in a new project
Use a supported Node release, then run these from the project directory:
npm init -y
npm install --save-dev --save-exact gulp gulp-cli sass browser-sync
Keep the resulting package-lock.json and use npm ci on subsequent installs. Review the chosen package versions before using them in an existing project.
Create src/scss/main.scss and public/index.html. The HTML should link to /styles.css. Save this as gulpfile.cjs:
const { series, watch } = require('gulp');
const sass = require('sass');
const { mkdir, writeFile } = require('node:fs/promises');
const browser = require('browser-sync').create();
async function styles() {
const result = sass.compile('src/scss/main.scss', { style: 'expanded' });
await mkdir('public', { recursive: true });
await writeFile('public/styles.css', result.css);
if (browser.active) browser.reload('styles.css');
}
function serve(done) {
browser.init({
server: { baseDir: 'public' },
listen: '127.0.0.1',
port: 3000,
open: false,
notify: false,
online: false,
ui: false,
}, done);
}
function observe() {
watch('src/scss/**/*.scss', styles);
watch(['public/**/*.html', 'public/**/*.js'])
.on('change', () => browser.reload());
}
exports.styles = styles;
exports.default = series(styles, serve, observe);
Start it with:
npx gulp --gulpfile gulpfile.cjs
Open http://127.0.0.1:3000/. Edit SCSS in src/scss, not the generated CSS; stop the watcher with Ctrl+C. Keep the output directory out of the Sass watch pattern to avoid a rebuild loop.
If the site uses PHP
BrowserSync's static server cannot execute PHP. Start your existing local PHP server separately, replace server with proxy: 'http://127.0.0.1:8000', and include public/**/*.php in the refresh watcher. Both are development tools, not public production servers.
This example does not promise automatic support for every browser. Add a deliberate Browserslist/PostCSS step only if the site's browser targets require it. Keep source maps and secrets out of public production output.
References: Gulp tasks, Dart Sass compile API, and BrowserSync options.
Original version13 February 2018
Kept here for reference and earlier links. The updated guide above is the recommended starting point; older code may depend on retired services or different software versions.
Using gulp to help organise and control your project assets is a great tool, but trying to set up the config each time can be annoying.
guwii has created the below config (gulpfile.js) to be the best fit for the majority of starter web projects so we hope you find it useful too.
It pipes style changes through autoprefixer to help support all browsers by default, as well as utilising browser-sync and connect-sync to start you up with a simple local PHP server - with browsersync injecting all the style changes and also auto-refreshing multiple devices.
If you're new to gulp you'll have to create a few files (gulpfile.js and package.json) in the root of your project and then run a few terminal commands to get yourself set up.
This isn't meant to be a full tutorial, but hopefully it can provide you with a re-usable resource for future projects—to copy-paste the bits you'll use often:
gulpfile.js
var gulp = require('gulp'),
autoprefixer = require('gulp-autoprefixer'),
sourcemaps = require('gulp-sourcemaps'),
connect = require('gulp-connect-php'),
sass = require('gulp-ruby-sass'),
browserSync = require('browser-sync');
var output = './css';
var autoprefixerOptions = {
browsers: ['last 2 versions']
};
gulp.task('styles', function () {
return sass('sass/style.scss', { style: 'compressed', sourcemap:true })
.pipe(sourcemaps.init())
.pipe(autoprefixer(autoprefixerOptions))
.pipe(sourcemaps.write())
.pipe(sourcemaps.write('maps', {
includeContent: false,
sourceRoot: 'source'
}))
.pipe(gulp.dest(output))
.pipe(browserSync.stream({ match: '**/*.css' }));
});
gulp.task('connect-sync', function () {
connect.server({}, function () {
browserSync({
proxy: '127.0.0.1:8000'
});
});
});
gulp.task('watch', function () {
gulp.watch("sass/**", ['styles']);
gulp.watch(['js/**/*.js', '*.html', '**/*.php']).on('change', browserSync.reload);
});
gulp.task('default', ['styles', 'connect-sync'], function () {
gulp.start('watch');
});
package.json
{
"name": "guwii gulp",
"version": "1.0",
"description": "guwii's quick gulp setup",
"author": "guwii",
"main": "gulpfile.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"license": "ISC",
"devDependencies": {
"browser-sync": "^2.24.5",
"gulp-autoprefixer": "^5.0.0",
"gulp-connect-php": "^1.0.3",
"gulp-ruby-sass": "^3.0.0",
"gulp-sourcemaps": "^2.6.4"
},
"dependencies": {
"gulp": "^3.9.1"
}
}
Finally, setting it up:
You first of all need to install node.
Then in terminal, run:
cd /your/directory/here
sudo npm install gulp -g
npm install --save-dev
gulp
Keep exploring