Skip to content

How I Load JavaScript Libraries in Ghost Themes

By Ahmad Ajmi

This post began as a Ghost Forum reply. The question was how to load an external JavaScript library in a theme. I will show different ways to load a script, the difference between each one, and the method I use in my Ghost themes.

Loading From CDN

Loading a library from a CDN is the simplest option. Add the library first, then run the code that depends on it. The order is essential.

<script src="https://unpkg.com/typewriter-effect@latest/dist/core.js"></script>
<script>
  var app = document.getElementById('app');
  // ...
</script>

This approach leaves loading and caching under the CDN’s control. For a production theme, use an exact package version instead of @latest. This keeps a new library release from changing your site unexpectedly.

Loading From node_modules

During local development, you might try to reference the installed file directly:

<script src="node_modules/typewriter-effect/dist/core.js"></script>
<script>
  var app = document.getElementById('app');
  // ...
</script>

This path will not exist in an uploaded theme unless you include node_modules in the final zip. That would make the theme unnecessarily large, so copy or bundle only the files the browser needs.

Here Is How I Do It

I use Gulp to combine the scripts into one browser-ready file. This includes third-party libraries and the theme script (/assets/js/app.js).

1.

Install the library with npm. It will be recorded in package.json.

npm install typewriter-effect

2.

Add the library to the gulpfile.js file JavaScript task. Here is a simplified example.

  gulp.task('js', function () {
    return gulp.src([
      './node_modules/typewriter-effect/dist/core.js',
      './assets/js/app.js'
    ])
      .pipe(concat('app.js'))
      .pipe(rename({ suffix: '.min' }))
      .pipe(gulp.dest('./assets/js'));
  });

I will have the app.min.js file by running this task, which I add to the theme default.hbs file.

<script src="{{asset 'js/app.min.js'}}"></script>

I have another task to zip the theme, which will exclude the node_modules directory.

Looking for production‑ready designs? Explore premium Ghost themes. Or get them all in the Aspire Themes bundle.

gulp.task('zip', function () {
  return gulp.src([
    './**',
    '!node_modules/**',
    '!bower_components/**',
    '!.git/**',
    '!.DS_Store'
  ], { dot: true })
    .pipe(zip('beirut.zip'))
    .pipe(gulp.dest('../'));
});

Here is a complete example of the gulpfile.js.

More from the Blog

Latest Ghost Themes