Zero-config React development environment and static site generator
npm install -g @compositor/x0- Zero-config
 - Hot-loading development environment
 - Works with virtually any React component*
 - No confusing APIs
 - Automatic file system based routing
 - Exports static HTML
 - Exports JS bundles
 - Works with CSS-in-JS libraries like styled-components and emotion
 - Support for async data fetching
 
* Custom webpack configuration is required for components that rely on webpack-based features
x0 componentsOptions:
-o --open       Open dev server in default browser
-p --port       Custom port for dev server
-t --template   Path to custom HTML template
--webpack       Path to custom webpack configuration
x0 components -op 8080Export static HTML and client-side bundle
x0 build componentsExport static HTML without bundle
x0 build components --staticOptions
-d --out-dir    Output directory (default dist)
-s --static     Output static HTML without JS bundle
-t --template   Path to custom HTML template
--webpack       Path to custom webpack configuration
Use the async getInitialProps static method to fetch data for static rendering.
This method was inspired by Next.js.
const Index = props => (
  <h1>Hello {props.data}</h1>
)
Index.getInitialProps = async () => {
  const fetch = require('isomorphic-fetch')
  const res = await fetch('http://example.com/data')
  const data = await res.json()
  return { data }
}A custom App component can be provided by including an _app.js file.
The App component uses the render props pattern to provide additional state and props to its child routes.
// example _app.js
import React from 'react'
export default class extends React.Component {
  state = {
    count: 0
  }
  update = fn => this.setState(fn)
  render () {
    const { render, routes } = this.props
    return render({
      ...this.state,
      decrement: () => this.update(s => ({ count: s.count - 1 })),
      increment: () => this.update(s => ({ count: s.count + 1 }))
    })
  }
}The App component can also be used to provide a common layout for all routes.
// example _app.js
import React from 'react'
import Nav from '../components/Nav'
import Header from '../components/Header'
import Footer from '../components/Footer'
export default class extends React.Component {
  render () {
    const {
      render,
      routes
    } = this.props
    const route = routes.find(route => route.path === props.location.pathname)
    return (
      <React.Fragment>
        <Nav />
        <Header
          route={route}
        />
        {render()}
        <Footer />
      </React.Fragment>
    )
  }
}x0 supports server-side rendering for styled-components and emotion with zero configuration.
To enable CSS rendering for static export, ensure that styled-components is installed as a dependency in your package.json
"dependencies": {
  "styled-components": "^3.2.6"
}Ensure emotion is installed as a dependency in your package.json
"dependencies": {
  "emotion": "^9.1.3"
}Default options can be set in the x0 field in package.json.
"x0": {
  "static": true,
  "outDir": "site",
  "title": "Hello",
}Head elements such as <title>, <meta>, and <style> can be configured with the x0 field in package.json.
"x0": {
  "title": "My Site",
  "meta": [
    { "name": "twitter:card", "content": "summary" }
    { "name": "twitter:image", "content": "kitten.png" }
  ],
  "links": [
    {
      "rel": "stylesheet",
      "href": "https://fonts.googleapis.com/css?family=Roboto"
    }
  ]
}A custom HTML template can be passed as the template option.
"x0": {
  "template": "./html.js"
}// example template
module.exports = ({
  html,
  css,
  scripts,
  title,
  meta = [],
  links = [],
  static: isStatic
}) => `<!DOCTYPE html>
<head>
  <title>{title}</title>
  ${css}
</head>
<div id=root>${html}</div>
${scripts}
`x0 creates routes based on the file system, using react-router.
To set the base URL for static builds, use the basename option.
"x0": {
  "basename": "/my-site"
}To link between different components, install react-router-dom and use the Link component.
npm i react-router-domimport React from 'react'
import { Link } from 'react-router-dom'
export default () => (
  <div>
    <h1>Home</h1>
    <nav>
      <Link to='/'>Home</Link>
      <Link to='/about'>About</Link>
    </nav>
  </div>
)x0 includes support for the Compositor JSX file format.
---
title: Hello
scope: import * as scope from 'rebass'
---
<Box px={2} py={4}>
  <Heading>
    {props.title}
  </Heading>
</Box>x0 includes support for the MDX file format.
import { Box } from 'rebass'
# Hello MDX
<Box p={4} bg='tomato'>
  Beep Boop
</Box>Webpack configuration files named webpack.config.js will automatically be merged with the built-in configuration, using webpack-merge.
To use a custom filename, pass the file path to the --webpack flag.
// webpack.config.js example
module.exports = {
  module: {
    rules: [
      { test: /\.txt$/, loader: 'raw-loader' }
    ]
  }
}See the example.
- Compositor JSX
 - MDX
 - React Router
 - Mini HTML Webpack Plugin
 - Styled Components
 - Emotion
 - webpack
 - Create React App
 - Next.js
 - Gatsby
 - React-Static