# sintaxi/harp: A Zero-Configuration Static Server That Compiles Templates on Request

> Harp serves EJS, Jade, Markdown, Sass, SCSS and CoffeeScript as HTML, CSS and JavaScript without a build step, and can export the result to plain files. It is a small tool with a narrow fit, and the repository's own release history says a lot about how much to expect from it.

**sintaxi/harp** — Static Web Server/Generator/Bundler

- Repository: https://github.com/sintaxi/harp
- Website: https://harp.sh
- Stars: 4,994 · Forks: 332
- Language: JavaScript
- License: not declared
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/sintaxi-harp

## What Harp actually removes from a static site workflow

Most static site tooling asks you to declare a pipeline before you can write a page. You pick a generator, install plugins, write a config file, and only then does a template turn into HTML. Harp inverts that. The README describes it as a "zero-configuration web server with built in pre-processing", and the CLI help lists the conversions directly: .ejs to .html, .jade to .html, .md to .html, .sass and .scss to .css, .cjs and .jsx to .js. There is no config file to write for those mappings to happen.

The audience is the person who wants to hand-write a small site, share a layout across pages, keep content in Markdown, and end up with files they can drop on any static host. The README is explicit about the motivation: the author wanted "a lightweight web server that was powerful enough for me to abandon web frameworks for dead simple front-end publishing". That is a narrow claim, and it is worth reading it as one. Harp is not trying to be a general build system.

## How the server and the compiler share one code path

Harp has two modes and they are not separate implementations. Running the CLI with a single argument starts a server; running it with two arguments compiles. The library exposes the same split: harp.server(projectPath [,args]) returns a server you call listen on, and harp.compile(projectPath [,outputPath] [, callback]) writes the processed output. A third entry point, harp.mount, is documented for use as Connect or Express middleware, which is why connect and send appear in the dependency list.

The processing model is directory-driven. Files are read from the source tree, run through the matching pre-processor based on extension, and served or written with the extension swapped. Data comes from two documented sources: _data.json for directory data and _data.js for dynamic build data. Layouts and partials are the other half of the model, with the CLI help showing the partial call shape: partial("_path/to/partial", { "title": "Hello World" }). The README also mentions built in LRU caching in production mode, which is what keeps a template from being re-rendered on every request when you are not editing it.

## Installing Harp and serving your first page

The README gives a global install through npm. It uses sudo, which is worth noticing: on most modern Node setups a global install does not need elevated permissions, and running it as root can leave files owned by root in your npm prefix.

```bash
sudo npm install -g harp
```

The quick start then creates a directory and points Harp at it. The README's example is a single command with a path argument, and the server comes up on port 9000.

```bash
mkdir ./public
harp ./public
```

At that point the README says your application is running at http://localhost:9000, and you can fill the directory with ejs, jade, md, sass and scss files that get processed automatically. Adding an index.md or index.ejs in that directory gives you a page without any further setup. If you want a different port or a different bind address, the CLI documents -p, --port (default 9000) and -h, --host (default 0.0.0.0). Note that -h is listed twice in the help output, once for host and once for help, which is the kind of detail that tells you the CLI surface has not been reworked recently.

Compiling is the same command with a second path. The README says the output folder is then ready to publish at a static host such as Surge.sh.

```bash
harp ./public ./build
```

## Where Harp stops being the right tool

The supported pre-processor list is short and it is closed. EJS, Jade, Markdown, Sass (SCSS) and Sass are what the README names. There is no plugin API described, no loader system, and no documented way to add a processor of your own. If your site depends on a template language outside that list, Harp is not a tool you extend. You replace it.

Two more limits are visible in the repository. First, the README marks Markdown as "(Unsanitized)", which means raw HTML in a Markdown file passes through. That is fine for content you control and a problem for content you do not. Second, the dependency list is a snapshot of a particular era of the Node ecosystem: connect 3.7.0, send 1.2.1, basic-auth 2.0.1. Those are the pieces that handle request routing, file serving and authentication, and they define the ceiling on what the server will do. If you need streaming, server-side rendering, or anything beyond static file delivery with pre-processing, this is the wrong layer.

The release history is the clearest signal. The most recent release listed is v0.40.3 on 2021-06-07, described as a "security upgrade --deny-symlinks". Before it, v0.40.2 on 2021-06-02 was a "security patch [Unauthorized File Access]". Two security releases five days apart, and nothing published since. The package.json version is 0.50.1, which does not match any listed release, so the published npm artifact and the repository's tagged releases are not obviously in step. The last push to the repository was on 2026-07-06, so work has happened since those releases, but the release notes do not describe what shipped and the README does not document --deny-symlinks or explain when you would need it.

## What to use instead when Harp's model does not fit

Eleventy is the closest comparison in intent and the furthest in mechanism. Both take a directory of templates and produce static files. The difference is that Eleventy is configured: you declare template engines, input and output directories, and collections in a config file, and it supports a long list of template languages with a plugin system on top. Harp's whole pitch is that this configuration does not exist, and the price of that is that you cannot change the behavior. If your project outgrows the five documented pre-processors, Eleventy is where you go, and you pay for it with a config file and a build step that Harp deliberately does not have.

## Licence, maintenance and the cost of upgrading

The README carries an MIT-style permission grant, copyright 2012 to 2021 Chloi Inc, permitting use, modification, distribution and sublicensing provided the notice is included, with the software provided "AS IS" and no warranty. The repository also contains a SECURITY.md file, which is where you should look for the project's own statement on reporting and handling vulnerabilities. This is a description of the licence text, not legal advice; if the terms matter to your organization, have someone qualified read them.

Upgrade cost is the harder question. The dependency list pins exact versions rather than ranges for most entries, and several of those pins (connect 3.7.0, send 1.2.1, basic-auth 2.0.1) sit in the request path. Moving them forward is not a version bump you can do from the outside; it is a change to Harp. The two 2021 releases were both security fixes, and the README does not document the --deny-symlinks flag that the newer of them introduced, so there is no published guidance on when to set it. Treat the pinned dependency set as the real maintenance surface, and check whether anything you deploy with Harp is exposed to a network before you assume the 2021 patches cover you.

## Conclusion

Harp fits small sites where layout and partial inheritance plus a handful of pre-processors are enough, and where the author wants to publish plain files to a static host. It does not fit projects that need plugins, incremental builds, modern JavaScript bundling, or a documented security posture, and the last release was v0.40.3 on 2021-06-07, so anyone deploying it should read SECURITY.md and decide whether the --deny-symlinks flag is required for their setup before putting it on a network.

## FAQ

### What is harp an acronym for?

The project is not presented as an acronym. The README and package.json describe it as a "Static Web Server/Generator/Bundler", and the name is written as Harp throughout.

### How do I install Harp?

The README gives a single global npm install command: sudo npm install -g harp. After that, running harp ./public from a directory starts the server on port 9000.

### Which template languages does Harp process?

The README and CLI help list EJS, Jade, Markdown, Sass (SCSS) and Sass, mapping .ejs, .jade and .md to .html, .sass and .scss to .css, and .cjs and .jsx to .js. Markdown is marked "(Unsanitized)" in the README.

### Can Harp compile a project to static files instead of serving it?

Yes. The README shows harp ./public ./build, and states that the resulting output folder is ready to publish at a static host such as Surge.sh.

### Can Harp be used as a library or with Express?

The README documents harp.server(projectPath [,args]), harp.compile(projectPath [,outputPath] [, callback]) and harp.mount, and shows harp.mount used alongside express.static as middleware.

### When was Harp last released?

The most recent release listed is v0.40.3 on 2021-06-07, a "security upgrade --deny-symlinks". The preceding release, v0.40.2 on 2021-06-02, was a security patch for unauthorized file access.

## Sources

- [Issues](https://github.com/sintaxi/harp/issues)
- [Project website](https://harp.sh)
- [README](https://github.com/sintaxi/harp/blob/master/README.md)
- [Releases](https://github.com/sintaxi/harp/releases)
- [sintaxi/harp on GitHub](https://github.com/sintaxi/harp)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sintaxi-harp
