npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details


  • User packages



Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.


Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner




A hapi view engine for React components.





A hapi view engine for React components.

Build Status Dependency Status Peer Dependency Status Dev Dependency Status

By default rendering is done using ReactDOMServer.renderToStaticMarkup. You can also choose to use ReactDOMServer.renderToString, preserving the data-react-id attributes so re-mounting client side is possible.


$ npm install hapi-react-views

Note: Your project should have it's own react and react-dom dependencies installed. We depend on these via peerDependencies.


Configuring the server manually:

const Hapi = require('@hapi/hapi');
const HapiReactViews = require('hapi-react-views');
const Vision = require('@hapi/vision');

    presets: ['@babel/preset-react', '@babel/preset-env']

const main = async function () {
    const server = Hapi.Server();

    await server.register(Vision);

        engines: {
            jsx: HapiReactViews
        compileOptions: {}, // optional
        relativeTo: __dirname,
        path: 'views'

    await server.start();

    console.log(`Server is listening at ${}`);


Note: As of hapi-react-views v4.x your project must register a transpiler such as babel. An alternative to this is to transpile ahead of time and save the result to file.

Note: As of hapi v9.x, your project must register the vision plugin in order for the server.views() and server.render() methods to be available.



Please refer to the vision docs on server.views(options) for complete details.

We'll be focusing on the compileOptions property that you can include when passing options to server.views.

The following compileOptions will customize how hapi-react-views works.

  • compileOptions - options object passed to the engine's compile function. Defaults to {}.
    • doctype - a simple string prepended to the response. Defaults to <!DOCTYPE html>
    • renderMethod - the method to invoke on ReactDOMServer to generate our output. Available options are renderToStaticMarkup and renderToString. Defaults to renderToStaticMarkup.
    • removeCache - since transpilers tend to take a while to startup, we can remove templates from the require cache so we don't need to restart the server to see changes. Defaults to 'production' !== process.env.NODE_ENV.
    • removeCacheRegExp - a RegExp pattern string, matching modules in require cache will be removed. Defaults to undefined.
    • layout - the name of the layout file to use.
    • layoutPath - the directory path of where layouts are stored.
    • layoutRenderMethod - same as renderMethod but used for layouts. Defaults to renderToStaticMarkup.

You can override all these compileOptions at runtime.

const context = { name: 'Steve' };
const renderOpts = {
    runtimeOptions: {
        doctype: '<!DOCTYPE html>',
        renderMethod: 'renderToString'

const output = await server.render('template', context, renderOpts);

Please refer to vision's docs on server.render(template, context, [options], callback) for complete details.


Before you can run the examples, you need to clone this repo and install the dependencies.

$ git clone
$ cd hapi-react-views
$ npm install

Rendering a simple page

This example renders a component as HTML output. View the code.

$ npm run simple-example

Rendering with layouts

Wrapper style layouts

This example renders components as HTML adding the idea of using wrapper layouts. The wrapping is handled by this module, so it may feel like a bit of magic since there is no direct dependency to the layout in your component views. View the code.

$ npm run layout-example

Component style layouts

This example renders components as HTML but adds the idea of using component layouts. The component layout is a direct dependency of your view components with no magic handling by this module. View the code.

$ npm run layout-component-example

Remounting on the client (universal/isomorphic)

This example demonstrates the idea of rendering the full page on the server and remounting the app view on the client side as a way to to create universal (aka isomorphic) applications.

It uses the wrapper layout feature, making it easy for the layout to be rendered without data-react-id attributes and the app view to be rendered with them. View the code.

$ npm run remount-example



Don't forget

What you create with hapi-react-views is more important than hapi-react-views.