npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

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.

About

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 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-ssr-fork

v1.0.1

Published

React SSR Fork facilitates rendering different content on server and client side.

Readme

React SSR Fork

React SSR Fork facilitates rendering different content on server and client side, and solves hydration mismatch issue.

Features

  • Provides <Client> component to render client side content, and <Server> for server side
  • Automatically solves the hydration issue of mismatched client and server side content
  • Prevents unecessary client side re-renders when solving hydration mismatch
  • Requires minimum setup and is easy to use.

Installation

Install the library:

npm install --save react-ssr-fork

Usage

Wrap your main application component inside <ForkProvider>. This component contains the business logic of solving hydration mismatch issue, also provides context for <Client> and <Server> components.

  1. Your client side entry might look like this (<ForkProvider> wrapping is obligatory):
// client.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import { ForkProvider } from 'react-ssr-fork';
import App from 'your-components/App';

ReactDOM.hydrate(
  <ForkProvider>
    <App />    
  </ForkProvider>,
  document.getElementById('root')
);
  1. And your server side entry file could look this way (<ForkProvider> wrapping is obligatory):
// server.jsx
import React from 'react';
import { renderToString } from 'react-dom/server';
import { ForkProvider } from 'react-ssr-fork';
import App from 'your-components/App.jsx';

const content = renderToString(
  <ForkProvider>
    <App />
  </ForkProvider>
);
// ...
  1. Then use <Client> component to render specifically client side content, and respectively <Server> to render server side content. Your <App> component might look like this:
// App.jsx
import React from 'react';
import { Client, Server } from 'react-ssr-fork';

export default function App() {
  return (
    <div>
      <Client>
        I run on client
      </Client>
      <Server>
        I run on server
      </Server>
    </div>
  );
}

Here's what happens when you run the application:

  • On server side <App> simply renders <div>I run on server</div>
  • On client side during hydration <App> renders <div>I run on server</div> (to match the content sent from server), then right away re-renders to actual client content <div>I run on client</div>.

Requirements

  • On both client and server sides <Client> and <Server> must to be wrapped inside <ForkProvider>
  • Requires React 16.3 and above

Why not use this.state.isCient approach?

ReactDOM.hydrate() documentation suggests solving hydration mismatch warning using two-pass rendering and this.state.isClient flag. Here's a simple imlementation:

import React, { Component } from 'react';

class Message extends Component {
  state = { isClient: false }

  render() {
    return (
      <div>
        {this.state.isClient ? 'I run on server' : 'I run on client'}
      </div>
    );
  }

  componentDidMount() {
    this.setState({ isClient: true });
  }
}

ReactDOM.hydrate(
  <Message />,
  document.getElementById('root')
);

On client side during initial render (hydration) this.state.isClient is false. Thus <Message> outputs <div>I run on server</div>. This output matches the one sent from server side, and React doesn't throw any mismatch warnings during hydration.

Right away after mounting of <Message>, componentDidMount() method is invoked and this.state.isClient becomes true. As result <Message> renders <div>I run on client</div>.

As described above, solving hydration mismatch using two-pass rendering works.

But there is a drawback. If a new instance of <Message> is rendered on the client side on later stages, two-pass rendering will be applied even if that's unnecessary. This makes your component slower. That's the problem solved by React SSR Fork library, which prevents unnecessary two-pass rendering when this is not necessary.

Unit testing

React SSR Fork components faciliate unit testing of your components.

<ForkProvider> accepts a special boolean prop canUseDom meant to indicate manually the client or server environment in your unit tests. For example:

import React from 'react';
import { mount } from 'enzyme';

import { ForkProvider } from 'react-ssr-fork';

function App() {
  return (
    <div>
      <Client>
        I run on client
      </Client>
      <Server>
        I run on server
      </Server>
    </div>
  );
}

describe('<App>', function () {
  test('renders client content on client side', function () {
    const wrapper = mount(
      // Client environment: canUseDom=true
      <ForkProvider canUseDom={true}>
        <App />
      </ForkProvider>
    );
    expect(wrapper.contains('I run on client')).toBe(true);
    expect(wrapper.contains('I run on server')).toBe(false);
  });

  test('renders server content on server side', function () {
    const wrapper = mount(
      // Server environment: canUseDom=false
      <ForkProvider canUseDom={false}>
        <App />
      </ForkProvider>
    );
    expect(wrapper.contains('I run on client')).toBe(false);
    expect(wrapper.contains('I run on server')).toBe(true);
  });
});

License

Licensed under MIT