Skip to content

JavaScript Syntax Highlighters

Jake provides syntax highlighting plugins for three popular JavaScript libraries: highlight.js, Shiki, and Prism.js. Each plugin exports the grammar in the format that library expects, following standard conventions.

LibraryBest ForSizeNotes
highlight.jsMost websites~2KBSimple API, widely supported
ShikiStatic sites, VS Code accuracy~8KB grammarTextMate grammar, best accuracy
Prism.jsExisting Prism sites~1.5KBLightweight, extensible

See how each library renders Jake code:

highlight.js Loading...
Shiki Loading...
Prism.js Loading...

All three packages are available on npm:

Terminal window
npm install highlightjs-jake
npm install prism-jake
npm install shiki-jake

You can also load them directly from jakefile.dev/libs/:

  • https://jakefile.dev/libs/highlightjs-jake.min.js
  • https://jakefile.dev/libs/prism-jake.min.js
  • https://jakefile.dev/libs/shiki-jake.tmLanguage.json

Browser:

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github-dark.min.css">
</head>
<body>
<pre><code class="language-jake">
task build:
echo "Building..."
</code></pre>
<!-- Load highlight.js core -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
<!-- Load Jake language -->
<script src="https://jakefile.dev/libs/highlightjs-jake.min.js"></script>
<script>
// Register Jake syntax (standard highlight.js API)
hljs.registerLanguage('jake', hljsDefineJake);
hljs.registerLanguage('jakefile', hljsDefineJake);
// Highlight all code blocks
hljs.highlightAll();
</script>
</body>
</html>

Node.js / ES Modules:

import hljs from 'highlight.js/lib/core';
import jake from 'highlightjs-jake';
// Register the language (standard highlight.js pattern)
hljs.registerLanguage('jake', jake);
hljs.registerLanguage('jakefile', jake);
// Highlight code
const code = `task build:
echo "Building..."`;
const result = hljs.highlight(code, { language: 'jake' });
console.log(result.value);

Browser:

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css">
</head>
<body>
<pre><code class="language-jake">
task build:
echo "Building..."
</code></pre>
<!-- Load Prism.js core -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
<!-- Load Jake language (auto-registers when Prism is global) -->
<script src="https://jakefile.dev/libs/prism-jake.min.js"></script>
</body>
</html>

Node.js / ES Modules:

import Prism from 'prismjs';
import jake from 'prism-jake';
// Register the language (standard Prism pattern)
Prism.languages.jake = jake;
Prism.languages.jakefile = jake;
// Highlight code
const code = `task build:
echo "Building..."`;
const html = Prism.highlight(code, jake, 'jake');
console.log(html);

Basic Usage:

import { createHighlighter } from 'shiki';
import jake from 'shiki-jake';
// Create highlighter with Jake language
const highlighter = await createHighlighter({
themes: ['github-dark'],
langs: [jake] // Pass grammar directly
});
// Highlight code
const code = `task build:
echo "Building..."`;
const html = highlighter.codeToHtml(code, {
lang: 'jake',
theme: 'github-dark'
});
console.log(html);

Load Dynamically:

import { createHighlighter } from 'shiki';
import jake from 'shiki-jake';
const highlighter = await createHighlighter({
themes: ['github-dark'],
langs: [] // Start with no languages
});
// Load Jake when needed
await highlighter.loadLanguage(jake);
const html = highlighter.codeToHtml(code, {
lang: 'jake',
theme: 'github-dark'
});

With Astro:

astro.config.mjs
import { defineConfig } from 'astro/config';
import jake from 'shiki-jake';
export default defineConfig({
markdown: {
shikiConfig: {
themes: {
light: 'github-light',
dark: 'github-dark',
},
langs: [jake],
},
},
});

With VitePress:

.vitepress/config.js
import { defineConfig } from 'vitepress';
import jake from 'shiki-jake';
export default defineConfig({
markdown: {
languages: [jake],
},
});

From CDN (TextMate Grammar):

import { createHighlighter } from 'shiki';
// Fetch the Jake grammar from CDN
const grammar = await fetch('https://jakefile.dev/libs/shiki-jake.tmLanguage.json')
.then(r => r.json());
// Create highlighter with Jake language
const highlighter = await createHighlighter({
themes: ['github-dark'],
langs: [{
name: 'jake',
scopeName: 'source.jake',
aliases: ['jakefile'],
...grammar
}]
});
const html = highlighter.codeToHtml(code, {
lang: 'jake',
theme: 'github-dark'
});

Each package follows the standard pattern for its library:

highlight.js:

hljs.registerLanguage('jake', definitionFunction);

Prism.js:

Prism.languages.jake = grammarObject;

Shiki:

createHighlighter({ langs: [grammarObject] });
// or
highlighter.loadLanguage(grammarObject);

These are the same patterns used by all other language packages in each ecosystem (go, python, rust, etc.).

The syntax highlighter packages are available on npm and GitHub:

All three libraries highlight the same Jake syntax elements:

  • Comments - Lines starting with #
  • Directives - @import, @dotenv, @require, @if, @needs, etc.
  • Keywords - task, file, as, if, else
  • Strings - Single, double, and triple-quoted
  • Interpolation - {{variable}} and {{function(arg)}}
  • Shell variables - $VAR, ${VAR}, $1, $@
  • Dependencies - [dep1, dep2]
  • Built-in functions - dirname(), env(), exists(), uppercase(), etc.
  • Platform keywords - linux, macos, windows, etc.
  • Command prefixes - @, -

Here’s what a fully highlighted Jakefile looks like:

# Build configuration
CC := gcc
CFLAGS := -Wall -O2
@import "common.jake"
@dotenv
task build target="release": [clean]
@if eq(target, "debug")
echo "Debug build"
{{CC}} {{CFLAGS}} -g src/*.c -o bin/app
@else
echo "Release build"
{{CC}} {{CFLAGS}} src/*.c -o bin/app
@end
task clean:
rm -rf bin/
file bin/app: [src/main.c, src/utils.c]
mkdir -p bin
{{CC}} {{CFLAGS}} $^ -o $@