
Research
SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains
An emerging npm supply chain attack that infects repos, steals CI secrets, and targets developer AI toolchains for further compromise.
A blazing-fast static site generator with live reload and EJS support, designed for modern development workflows.
rstic is a blazing-fast, zero-config static site generator built with Node.js. It supports .html and .ejs templates, automatic file-based routing, and live reload powered by WebSockets. It's lightweight, pluggable, and perfect for developers who want fast iteration while building static websites.
<value>, <loop>, <if>, <include>, and inline expressions.rsticrc.* or rstic.config.* using cosmiconfig.json data file support for each templatepublic/ directory for static assetsdev, build, start)npm install --save-dev rstic
npx rstic dev
Starts the server on http://localhost:3003 with live reload for .ejs, .html, .json, and .css.
npx rstic build
Generates static HTML files in the dist/ directory based on the defined config.
npx rstic start
Serves the built dist/ directory with live preview.
project/
├── public/ # Static files (served directly)
├── src/
│ └── pages/
│ ├── index.ejs # Renders at "/"
│ ├── about.html # Renders at "/about"
│ ├── contact.ejs # Renders at "/contact"
│ └── blog/
│ ├── post.ejs # Renders at "/blog/post"
│ └── post.json # Injected into post.ejs
You can also use pages/ in the root folder instead of src/pages.
rstic uses cosmiconfig to allow flexible config loading:
Supported config filenames:
.rsticrc, .rsticrc.json, .rsticrc.yaml, .rsticrc.ts,
rstic.config.js, rstic.config.ts, etc.
Default config structure:
{
pagesDir: "src/pages",
outputDir: "dist",
watchDirs: ["src"],
watchFiles: [".html", ".ejs", ".css", ".js"],
supportFiles: [".html", ".ejs"],
publicDir: "public",
build: "server", // server or static
port: 3003,
}
rstic includes a custom HTML templating engine that processes your templates in two phases:
<include>, <loop>, <if>, and <value> tags.{{ }} placeholders.{{ expression }}Evaluate any valid JavaScript expression against the provided data context.
<p>Hello, {{ user.name.toUpperCase() }}!</p>
<!-- If data = { user: { name: 'Alice' } }, renders as: -->
<p>Hello, ALICE!</p>
Expressions run in a secure vm sandbox, and errors yield empty strings with a console warning.
<value key="path.to.value" />Injects a data property by key path (dot-separated).
<value key="site.title" />
<!-- If data = { site: { title: 'My Blog' } }, renders as: -->
My Blog
<loop data="items" var="item" index="i">...</loop>Iterates over an array in data, rendering the inner HTML for each element.
data: key in the root data that points to an array.var: variable name for the current item in the loop.index: variable name for the current index.<loop data="posts" var="post" index="idx">
<h2>{{ post.title }}</h2>
<p>Post #{{ idx + 1 }}: {{ post.excerpt }}</p>
</loop>
Given data = { posts: [ { title: 'Hello', excerpt: '...' }, ... ] }, renders one block per post.
<if condition="expression">...</if>Conditionally includes content if the expression (JavaScript) evaluates truthy.
<if condition="user.isAdmin">
<p>Welcome, administrator!</p>
</if>
The condition is evaluated in the same sandbox as inline expressions. If false or error, the tag is removed.
<include src="path/to/file.html" [attr="value"] />Embeds another template file, rendering it with the current data plus any additional attributes passed in.
src: path to the partial, relative to the current template’s directory.<include src="./partials/header.html" title="{{ site.title }}" />
This will read and render partials/header.html with data extended by { title: data.site.title }.
npx rstic --help
dev: Start Express dev server with live reloadbuild: Build static HTML to the output folderstart: Start static live server from build directoryPull requests are welcome! Open an issue first to discuss what you’d like to change.
Make sure to update tests as appropriate.
FAQs
A blazing-fast static site generator with live reload and EJS support, designed for modern development workflows.
We found that rstic demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
An emerging npm supply chain attack that infects repos, steals CI secrets, and targets developer AI toolchains for further compromise.

Company News
Socket is proud to join the OpenJS Foundation as a Silver Member, deepening our commitment to the long-term health and security of the JavaScript ecosystem.

Security News
npm now links to Socket's security analysis on every package page. Here's what you'll find when you click through.