Single Page Applications

Alembic is designed to be compiled up-front to reduce client-side JavaScript but you can still use it in JavaScript-based single page apps. Your framework will probably come with a bundler to use with it so this guide will cover a few.



  • Node.js v18+
  • npm v7+

Then install Alembic with NPM:

npm install --save-dev @openlab/alembic

These CSS variables need to be set to use Alembic:

:root {
/* A colour for the foremost thing, like the text in a box */
--color-foreground: black;

/* A colour for the backmost thing, like the background of a box */
--color-background: white;

/* The thickness of a border, like a box. Perhaps use a modular scale variable */
--border-thin: 0.2rem;

/* The maximum width of text on the body of a page, to make it more readable */
--measure: 60ch;

Getting started

Your bundler should pick up an import to Alembic assets and process the code it its own way, .e.g to minify or optimise them. These are the files you can import:

  • @openlab/alembic (same as module.js)
  • @openlab/alembic/module.js
  • @openlab/alembic/reset.css
  • @openlab/alembic/everything.js
  • @openlab/alembic/everything.css
  • @openlab/alembic/tools.js

It's worth noting that Alembic only supports ESM.

If you just want an import and everything will work, import everything.js from your JavaScript and link to everything.css from your CSS.

If you want to manually trigger Alembic client-side, import module.js like this:

import { allCustomElements, defineCustomElements } from '@openlab/alembic'

// Then whenever call this you want to trigger Alembic to run:

and then in your CSS file:

@import '@openlab/alembic/everything.css';

Vite + vue

When using Vite, you also need to tell it which elements from Alembic are custom elements, so it knows not to process these. Create or update your Vite config to include:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { allCustomElements } from '@openlab/alembic'

export default defineConfig({
plugins: [
template: {
compilerOptions: {
isCustomElement: (tag) => allCustomElements.has(tag),

Last tested with vite@3 and @vitejs/plugin-vue@3


When using Parcel, do the same initial setup but you'll need npm: prefixes in your imports in JavaScript:

import 'npm:@openlab/alembic/everything.js'

and in CSS:

@import 'npm:@openlab/alembic/everything.css';


See the api docs for the tools available to hook things up yourself.