Sandstone.js is a "batteries included" JavaScript library for writing smart reusable Web Components in a modern way.

Inspired by React components Sandstone provides familiar state management mechanisms and Virtual DOM, while also providing all of the sweetness of Web Components like Shadow DOM, "by-definition" server side rendering and ability to render from template tags and strings.


  1. Getting started
  2. Using stateless components
  3. Options
  4. Using JSX
  5. Browser support
  6. FAQ

Getting Started

Getting started is simple:

Step 1. Import Sandstone:

import { WebComponent, register } from 'sandstone';

Step 2. Create your component:

class SuperHeader extends WebComponent {
    render(props) {
        return (
                <h3>It's Superpowered!</h3>

Looks familiar? Sandstone components are written in the exact same way as React components.

Note: Because Sandstone uses Preact for rendering JSX, props and state are passed as arguments to the render() method for convenient destructuring. You can still use this.props and this.state if you want to, but it's not required.

Step 3. Register your custom tag:

register(SuperHeader, 'super-header');

Second argument is an optional tag name. If not set, component name converted to dash-case will be used.

Step 4. Use it!

<div id="main">
    <super-header text="This is not a simple header!"></super-header>

And you're good to go! Custom tag's attributes will be passed to this.props in your component and resulting HTML on the page will be:

    <h1>This is not a simple header!</h1>
    <h3>It's Superpowered!</h3>

Can I use stateless components?

Yes, you can! The above class example can be trimmed down to this:

const SuperHeader = ({ text }) => (
        <h3>It's Superpowered!</h3>


A third argument passed to Sandstone.register is an options object:

    useShadow: 'open' || 'closed',
    allowScripts: true

useShadow option enables Shadow DOM. Pass open for open mode and closed for closed. See the difference here.

allowScripts By default, all <script> tags will be removed from rendered markup. This option re-enables them and permits executing any JavaScript code within a component. Be careful with this option.

Notes on JSX

There are 3 ways to enable JSX with Sandstone:

  1. Using a Babel preset (easiest)

    // .babelrc
        "presets": ["sandstone"]
  2. By adding:

    /** @jsx Sandstone.h */


    /** @jsx h */
    import { h } from 'sandstone';

    on top of the file containing JSX. This will tell Babel to turn all JSX calls into Sandstone.h calls. This is useful if for instance you already have React in your project and don't wan't to overwrite all of JSX behavior.

  3. In .babelrc:

        "presets": [...],
        "plugins": [
                "pragma": "Sandstone.h" // default pragma is React.createElement

What browsers are supported?

Sandstone is written with the web platform in mind. According to, the current support for platform features is as follows:

Browser Support
Template Tags ❇️ Stable ❇️ Stable ❇️ Stable ❇️ Stable ❇️ Stable
Custom Elements ❇️ Stable ❇️ Stable ❇️ Stable 🛠 Developing 🤔 Considering
Shadow DOM ❇️ Stable ❇️ Stable ❇️ Stable 🛠 Developing 🤔 Considering
Module Scripts ❇️ Stable ❇️ Stable ❇️ >10.1 🏁 Flag in 54 🏁 Flag in 15
HTML Imports ❇️ Stable ❇️ Stable ⏱ On Hold ⏱ On Hold 🤔 Considering

And this is what the support looks like with the polyfill:

Polyfill Support
Template Tags ❇️ Stable ❇️ Stable ❇️ Stable ❇️ Stable ❇️ Stable
Custom Elements ❇️ Stable ❇️ Stable ❇️ Stable ☘️ Polyfill ☘️ Polyfill
Shadow DOM ❇️ Stable ❇️ Stable ❇️ Stable ☘️ Polyfill ☘️ Polyfill
Module Scripts ❇️ Stable ❇️ Stable ❇️ >10.1 ☘️ Polyfill ☘️ Polyfill
HTML Imports ❇️ Stable ❇️ Stable ☘️ Polyfill ☘️ Polyfill ☘️ Polyfill

Note: Sandstone does not include any polyfills. You are responsible for pollyfilling for your target browsers.


Q: I am morally opposed to JSX! How can I use this?

Sandstone also supports rendering from string. We'll get to that in a bit.

However using JSX provides a whole lot of awesome features that you'll be missing out.

Q: I'm morally opposed to Webpack and bundling! How can I use this?

Sandstone doesn't impose any build systems on you. All you need to get started is drop a script tag on the page.

The downside of not using a build system is unavailability of JSX via Babel. But you can still use string render and get all benefits of Virtual DOM, or use Sandstone.h directly to create components.

Q: I am morally opposed to HTML Imports!

We are too. Safari and Firefox aren't going to implement them, and they are just generally weird. Sandstone doesn't rely on them and we suggest not to use them.

Q: Do I need React to use this?

Nope. Sandstone is inspired by React components approach and uses Preact under the hood for features like Virtual DOM and linkState but it's not React nor does it require it.

Q: Can I have content inside of my custom elements?

Yes! By default all elements inside your custom tag will be passed to this.props.children. There's a flag to disable that behavior.

Q: Can I have other custom elements inside of my custom elements?

Yes! Sandstone supports infinite levels of component-ception, allthough it's better to use JSX for nesting things.

Q: I am morally supportive of imperative DOM manipulations. Will this still work?

Sandstone is your friend! If outside forces like jQuery decide to change your element's attributes, changes will be passed down to this.props and componentWillReceiveProps will be called as you would expect.

Q: Can I use React library XYZ to do ZYX?

No idea. Sandstone doesn't use React, it only uses JSX via Preact, so if library XYZ just does some JSX stuff and doesn't heavily depend on React core, it might work. If it doesn't, using preact-compat in your build might help, but no promises.

Q: How do I port my single page app to Sandstone?

Whoa whoa, hold your horses. Sandstone serves different purpose than React or Angular or Vue or what have you. You're not supposed to be building an SPA with this.

Sandstone is not an SPA framework, it's a Web Components library.

Web components are a set of web platform APIs that allow you to create new custom, reusable encapsulated HTML tags to use in web pages and web apps.

What Sandstone does is allows you to create componens that are smarter than just a collection of tags and styles and allow you to do things like interactions, networking, etc.

If you want to build a dynamic single page app, this library is probably not the tool you're looking for.

Next: Component Structure →

results matching ""

    No results matching ""