Phantomake is a static site generator with specific goals:
- Distributed as a single, standalone executable
- When run on an existing static site, will (in most cases) output the exact same site with no changes
- Can reuse common code (headers/footers/common HTML) across several pages with templates and includes
- Can do pagination (e.g. for blog listings)
Phantomake is available as a terminal command or the PhantoGUI app for desktop use.
Phantomake is written in TypeScript and runs on Bun. PhantoGUI is built using Tauri.
Binaries and PhantoGUI installers for MacOS, Linux, and Windows are available from the Releases page. Or, use the links below to fetch the latest builds:
phantomake
standalone binary- PhantoGUI
- MacOS
- Windows Installer
- Linux
If you have Bun installed, you can also install Phantomake as a global package:
bun add -g https://github.com/Osmose/phantomake/releases/latest/download/source.tar.gz
Phantomake takes two arguments: a source directory and an output directory. It processes the source files and generates output files in the output directory:
phantomake /path/to/source /path/to/output
Phantomake will transform files that meet one of the following criteria:
- Any file with a
.ejs
extension will be processed as an EJS template. - Any file with a
.md
extension will be processed as Markdown. - Any text file (including
.ejs
or.md
files) with atemplate
value in YAML front matter will have a template applied to its output. - Any dotfile or dot directory (with a
.
at the start of its name) is not included in the output.
All files that don't match any of these are copied without changes from the source to the output.
See the full documentation for more information.
Let's say we have a header for our website that we don't want to have to copy-paste to every page whenever we update it. We can put this header in a separate file:
<!-- src/.header.html -->
<header class="header-container">
<h1>Phanto's Ghostlace Site</h1>
<nav class="links">
<a href="/">Home</a>
<a href="/blog">Blog</a>
</nav>
</header>
We can add the .ejs
extension to our HTML files and use the include
function of EJS to embed the content of header.html
in the generated output:
<!-- src/index.html.ejs -->
<html>
<head>
<title>Phanto's Ghostlace Site</title>
</head>
<body>
<!-- EJS templates use <% %> to mark template logic. The dash at the start
means "output the return value of this function". -->
<%- include('.header.html') %>
<h2>Homepage</h2>
<p>Welcome to Phanto's Ghostlace Site</p>
</body>
</html>
Now we can run Phantomake:
phantomake src output
This will create an output/index.html
file with our shared header:
<!-- output/index.html -->
<html>
<head>
<title>Phanto's Ghostlace Site</title>
</head>
<body>
<header class="header-container">
<h1>Phanto's Ghostlace Site</h1>
<nav class="links">
<a href="/">Home</a>
<a href="/blog">Blog</a>
</nav>
</header>
<h2>Homepage</h2>
<p>Welcome to Phanto's Ghostlace Site</p>
</body>
</html>
Phantomake is distributed under the ISC license.