reactql
Universal React+GraphQL starter kit: React 16, Apollo 2, MobX, Emotion, Webpack 4, GraphQL Code Generator, React Router 4, PostCSS, SSR
Top Related Projects
Set up a modern web app by running one command.
The React Framework
The best React-based framework with performance, scalability and security built in.
Develop. Preview. Ship.
The App Framework for Startups
Build Better Websites. Create modern, resilient user experiences with web fundamentals.
Quick Overview
ReactQL is a universal React + GraphQL starter kit, designed to get you up and running with a powerful web application stack quickly. It combines React for the frontend, GraphQL for efficient data fetching, and includes server-side rendering capabilities out of the box.
Pros
- Comprehensive starter kit with React, GraphQL, and server-side rendering
- Includes hot reloading for rapid development
- Provides a scalable project structure for large applications
- Comes with built-in TypeScript support
Cons
- May have a steeper learning curve for beginners due to its comprehensive nature
- Some users report occasional issues with dependency conflicts
- Documentation could be more extensive for advanced use cases
- Frequent updates may require keeping up with changes in the project structure
Code Examples
- Setting up a GraphQL query:
import { gql, useQuery } from '@apollo/client';
const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
`;
function UserProfile({ userId }) {
const { loading, error, data } = useQuery(GET_USER, {
variables: { id: userId },
});
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return <div>{data.user.name}</div>;
}
- Creating a React component with server-side rendering:
import React from 'react';
import { GetServerSideProps } from 'next';
interface Props {
message: string;
}
const ServerRenderedComponent: React.FC<Props> = ({ message }) => {
return <div>{message}</div>;
};
export const getServerSideProps: GetServerSideProps = async (context) => {
return {
props: {
message: 'This message was rendered on the server',
},
};
};
export default ServerRenderedComponent;
- Setting up a GraphQL mutation:
import { gql, useMutation } from '@apollo/client';
const ADD_TODO = gql`
mutation AddTodo($text: String!) {
addTodo(text: $text) {
id
text
completed
}
}
`;
function AddTodo() {
const [addTodo] = useMutation(ADD_TODO);
return (
<form
onSubmit={e => {
e.preventDefault();
addTodo({ variables: { text: input.value } });
input.value = '';
}}
>
<input ref={node => { input = node; }} />
<button type="submit">Add Todo</button>
</form>
);
}
Getting Started
-
Clone the repository:
git clone https://github.com/leebenson/reactql.git cd reactql
-
Install dependencies:
npm install
-
Start the development server:
npm run dev
-
Open your browser and navigate to
http://localhost:3000
to see your ReactQL app running.
Competitor Comparisons
Set up a modern web app by running one command.
Pros of Create React App
- Officially maintained by Facebook, ensuring long-term support and updates
- Extensive documentation and large community support
- Simpler setup process, ideal for beginners or quick prototyping
Cons of Create React App
- Less flexibility in configuration without ejecting
- Limited built-in features compared to ReactQL's full-stack approach
- No built-in GraphQL support
Code Comparison
ReactQL:
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';
const MyComponent = ({ data: { loading, error, users } }) => {
// Component logic here
};
export default graphql(gql`
query {
users {
id
name
}
}
`)(MyComponent);
Create React App:
import React, { useState, useEffect } from 'react';
function MyComponent() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch('/api/users')
.then(response => response.json())
.then(data => setUsers(data));
}, []);
// Component logic here
}
export default MyComponent;
The code comparison shows ReactQL's built-in GraphQL integration, while Create React App requires additional setup for similar functionality. ReactQL provides a more opinionated structure for GraphQL queries, whereas Create React App offers a blank slate for implementing data fetching methods.
The React Framework
Pros of Next.js
- Larger community and ecosystem, with more resources and third-party integrations
- Built-in server-side rendering and static site generation capabilities
- Regular updates and maintenance from a dedicated team at Vercel
Cons of Next.js
- Steeper learning curve for developers new to server-side rendering concepts
- Less flexibility in project structure compared to ReactQL's modular approach
- Potentially more complex configuration for advanced use cases
Code Comparison
ReactQL:
import React from 'react';
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';
const MyComponent = ({ data }) => (
<div>{data.loading ? 'Loading...' : data.user.name}</div>
);
Next.js:
import { useQuery } from '@apollo/client';
import gql from 'graphql-tag';
const GET_USER = gql`query { user { name } }`;
function MyComponent() {
const { loading, data } = useQuery(GET_USER);
return <div>{loading ? 'Loading...' : data.user.name}</div>;
}
Both ReactQL and Next.js offer solutions for building React applications with server-side rendering capabilities. ReactQL provides a more opinionated structure with built-in GraphQL integration, while Next.js offers a more flexible approach with a larger ecosystem. The choice between the two depends on project requirements, team expertise, and desired level of customization.
The best React-based framework with performance, scalability and security built in.
Pros of Gatsby
- Larger community and ecosystem with extensive plugins and themes
- Built-in performance optimizations like code splitting and prefetching
- Static site generation capabilities for improved SEO and load times
Cons of Gatsby
- Steeper learning curve due to its complex architecture
- Potentially slower build times for large sites
- Less flexibility for custom server-side rendering configurations
Code Comparison
ReactQL:
import React from 'react'
import { graphql } from 'react-apollo'
import gql from 'graphql-tag'
const MyComponent = ({ data }) => (
<div>{data.loading ? 'Loading...' : data.hello}</div>
)
Gatsby:
import React from 'react'
import { graphql } from 'gatsby'
export const query = graphql`
query MyQuery {
site {
siteMetadata {
title
}
}
}
`
const MyComponent = ({ data }) => (
<div>{data.site.siteMetadata.title}</div>
)
Both ReactQL and Gatsby provide GraphQL integration, but Gatsby's approach is more tightly coupled with its ecosystem and build process. ReactQL offers a more traditional React setup with Apollo Client, while Gatsby abstracts away much of the GraphQL complexity for static site generation.
Develop. Preview. Ship.
Pros of Vercel
- Comprehensive deployment platform with serverless functions and edge network
- Extensive documentation and community support
- Seamless integration with popular frameworks like Next.js
Cons of Vercel
- More complex setup for non-Next.js projects
- Potential vendor lock-in for certain features
- Limited customization options for advanced deployment scenarios
Code Comparison
Vercel (serverless function):
module.exports = (req, res) => {
const { name = 'World' } = req.query;
res.status(200).send(`Hello ${name}!`);
};
ReactQL (GraphQL query):
query {
users {
id
name
}
}
Summary
Vercel offers a robust deployment platform with excellent integration for Next.js projects, while ReactQL focuses on providing a boilerplate for React and GraphQL applications. Vercel excels in ease of deployment and scalability, but may be overkill for simpler projects. ReactQL provides a more focused starting point for React and GraphQL development but lacks the comprehensive deployment features of Vercel.
Choose Vercel for seamless deployment and scalability, especially with Next.js projects. Opt for ReactQL if you need a quick start with React and GraphQL without the full deployment platform.
The App Framework for Startups
Pros of Redwood
- Full-stack framework with integrated backend and frontend
- Built-in CLI for scaffolding and code generation
- Opinionated structure for better developer experience
Cons of Redwood
- Steeper learning curve due to its comprehensive nature
- Less flexibility in choosing individual technologies
- Relatively newer project with a smaller community
Code Comparison
ReactQL:
import React from 'react'
import { graphql } from 'react-apollo'
import gql from 'graphql-tag'
const MyComponent = ({ data: { loading, error, todos } }) => {
// Component logic here
}
Redwood:
import { useQuery } from '@redwoodjs/web'
const QUERY = gql`
query TodosQuery {
todos {
id
title
}
}
`
const MyComponent = () => {
const { loading, error, data } = useQuery(QUERY)
// Component logic here
}
ReactQL focuses on integrating React with GraphQL, while Redwood provides a more comprehensive full-stack solution. ReactQL offers more flexibility in choosing additional technologies, whereas Redwood enforces a specific structure and toolset. Redwood's CLI and scaffolding tools can speed up development, but may limit customization options compared to ReactQL's more open approach.
Build Better Websites. Create modern, resilient user experiences with web fundamentals.
Pros of Remix
- Full-stack framework with built-in server-side rendering and data loading
- Seamless integration with modern web APIs and progressive enhancement
- Active development and community support
Cons of Remix
- Steeper learning curve due to its full-stack nature
- Less flexibility in choosing backend technologies
Code Comparison
Remix (server-side data loading):
export async function loader({ params }) {
const user = await getUser(params.id);
return json({ user });
}
export default function UserProfile() {
const { user } = useLoaderData();
return <h1>{user.name}</h1>;
}
ReactQL (client-side data fetching):
import { useQuery } from '@apollo/client';
function UserProfile({ id }) {
const { data } = useQuery(GET_USER, { variables: { id } });
return <h1>{data?.user?.name}</h1>;
}
Summary
Remix offers a more integrated full-stack approach with server-side rendering and data loading, while ReactQL focuses on client-side React development with GraphQL integration. Remix may be better suited for complex web applications requiring server-side rendering, while ReactQL provides a simpler setup for React and GraphQL projects.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Universal front-end React + GraphQL starter kit, written in Typescript.
Features
Front-end stack
- React v16.8 (the one with hooks!) for UI.
- Apollo Client 2.5 (React) for connecting to GraphQL.
- MobX-React-Lite for declarative, type-safe flux/store state management.
- Emotion CSS-in-JS, with inline
<style>
tag generation that contains only the CSS that needs to be rendered. - Sass, Less and PostCSS when importing
.css/.scss/.less
files. - React Router 4 for declarative browser + server routes.
- GraphQL Code Generator v1.1 for parsing remote GraphQL server schemas, for automatically building fully-typed Apollo React HOCs instead of writing
<Query>
/<Mutation>
queries manually - Declarative/dynamic
<head>
section, using react-helmet.
Server-side rendering
- Built-in Koa 2 web server, with async/await routing.
- Full route-aware server-side rendering (SSR) of initial HTML.
- Universal building - both browser + Node.js web server compile down to static files, for fast server re-spawning.
- Per-request GraphQL store. Store state is dehydrated via SSR, and rehydrated automatically on the client.
- MobX for app-wide flux/store state, for automatically re-rendering any React component that 'listens' to state. Fully typed state!
- Full page React via built-in SSR component - every byte of your HTML is React.
- SSR in both development and production, even with hot-code reload.
Real-time
- Hot code reloading; zero refresh, real-time updates in development.
- Development web server that automatically sends patches on code changes, and restarts the built-in Web server for SSR renders that reflect what you'd see in production.
- WebSocket
subscription
query support for real-time data (just setWS_SUBSCRIPTIONS=1
in .env)
Code optimisation
- Webpack v4, with tree shaking -- dead code paths are automatically eliminated.
- Asynchronous code loading when
import()
'ing inside a function. - Automatic per-vendor chunk splitting/hashing, for aggressive caching (especially good behind a HTTP/2 proxy!)
- Gzip/Brotli minification of static assets.
- CSS code is combined, minified and optimised automatically - even if you use SASS, LESS and CSS together!
Styles
- Emotion, for writing CSS styles inline and generating the minimal CSS required to properly render your components.
- PostCSS v7 with next-gen CSS and automatic vendor prefixing when importing
.css
,.scss
or.less
files. - SASS and LESS support (also parsed through PostCSS.)
- Automatic vendor prefixing - write modern CSS, and let the compiler take care of browser compatibility.
- Mix and match SASS, LESS and regular CSS - without conflicts!
- CSS modules - your classes are hashed automatically, to avoid namespace conflicts.
- Compatible with Foundation, Bootstrap, Material UI and more. Simply configure via a
.global.(css|scss|less)
import to preserve class names.
Production-ready
- Production bundling via
npm run production
, that generates optimised server and client code. - Static compression using the Gzip and Brotli algorithms for the serving of static assets as pre-compressed
.gz
and.br
files (your entire app'smain.js.bz
- including all dependencies - goes from 346kb -> 89kb!) - Static bundling via
npm run build:static
. Don't need server-side rendering? No problem. Easily deploy a client-only SPA to any static web host (Netlify, etc.)
Developer support
- Written in Typescript with full type support, out the box (all external
@types/*
packages installed) - Heavily documented code
Quick start
Grab and unpack the latest version, install all dependencies, and start a server:
wget -qO- https://github.com/leebenson/reactql/archive/4.5.1.tar.gz | tar xvz
cd reactql-4.5.1
npm i
npm start
Your development server is now running on http://localhost:3000
Building GraphQL HOCs
By default, your GraphQL schema lives in schema/schema.graphql
To create fully Typescript-typed Apollo React HOCs based on your schema, simply put the query in a .graphql
anywhere inside the source folder, and run:
npm run gen:graphql
You can then import the query like we do in the HackerNews demo component:
// Query to get top stories from HackerNews
import { GetHackerNewsTopStoriesComponent } from "@/graphql";
And use it as follows:
<GetHackerNewsTopStoriesComponent>
{({ data, loading, error }) => (...)}
</GetHackerNewsTopStoriesComponent>
To get access to the underlying gql
-templated query (in case you need it for refetching, etc), in this case it'd be GetHackerNewsTopStoriesDocument
.
See GraphQL Code Generator for more details on how it works.
You can also edit codegen.yml in the root to point to a remote schema, or change the file location.
Development mode
Development mode offers a few useful features:
-
Hot code reloading. Make a change anywhere in your code base (outside of the Webpack config), and changes will be pushed down the browser automatically - without page reloads. This happens for React, Emotion, SASS - pretty much anything.
-
Full source maps for Javascript and CSS.
-
Full server-side rendering, with automatic Koa web server restarting on code changes. This ensures the initial HTML render will always reflect your latest code changes.
To get started, simply run:
npm start
A server will be started on http://localhost:3000
Production mode
In production mode, the following happens:
-
All assets are optimised and minified. Javascript, CSS, images, are all compiled down to static files that will appear in
dist
. -
Assets are also compressed into
.gz
(Gzip) and.br
(Brotli) versions, which are served automatically to all capable browsers. -
If files have been generated in a previous run, they will be re-used on subsequent runs. This ensures really fast server start-up times after the initial build.
To build and run for production, use:
npm run production
Files will be generated in ./dist
, and a server will also be spawned at http://localhost:3000
Clean the cached production build with npm run clean
, or run npm run clean-production
to both clean and re-run the production build, as needed.
Build mode
If you only want to build assets and not actually run the server, use:
npm run build:production
This is used in the Dockerfile, for example, to pre-compile assets and ensure faster start-up times when spawning a new container.
Static bundling for client-only SPAs
If you're targeting a client-only SPA and hosting statically, you probably don't want to run a Koa web server to handle HTTP requests and render React.
Instead, you can use static mode, which produces the client-side JS, CSS and assets files, along with an index.html
for minimal bootstrapping, and dumps them in dist/public
.
You can then upload the contents of that folder wherever you like - et voila, you'll have a working client-side Single Page App!
There are two static modes available -- for dev and production:
###Â Development (hot-code reload)
Just like the full-stack version, dev mode gives you hot code reloading, so changes to your local files will be pushed to the browser.
To activate static dev mode, just run:
npm run dev:static
Your client-side SPA will be online at http://localhost:3000, just like normal.
###Â Production (static deployment)
To build your client-side files ready for production deployment, run:
npm run build:static
You'll get everything in that 'regular' building provides you with plus a index.html
to bootstrap your JS, just without the server parts.
Modifying the index.html
template
If you want to make changes to the index.html
file that's used for static bundling, edit src/views/static.html
NPM commands
Here's a list of all the NPM script commands available out-the-box:
Command | What it does |
---|---|
npm run build:production | Builds production-ready client/server bundles, but doesn't start a server. |
npm run build:static | Builds production-ready client bundle and index.html ; ignores server bundling. |
npm run clean | Removes the dist folder, and any previously built client/server bundle. |
npm run dev | Runs a univeral dev server in memory; auto restarts on code changes and uses hot-code reload in the browser. Does not output anything to dist . |
npm run dev:static | Runs a client-only dev server using [src/views/static.html] as the template; full hot-code reload. Also doesn't output anything to dist . |
npm run production | Builds and runs a production-ready client/server bundle. If previously built, will re-use cached files automatically (run npm run clean to clear cache.) |
npm run production:clean | Same as above, but cleans dist first to ensure a fresh re-build. |
npm start | Shortcut for npm run dev . |
Project layout
The important stuff is in src.
Here's a quick run-through of each sub-folder and what you'll find in it:
-
src/components - React components. Follow the import flow at root.tsx to figure out the component render chain and routing. I've included an example component that shows off some Apollo GraphQL and MobX features, including incrementing a local counter and pulling top news stories from Hacker News (a live GraphQL server endpoint.)
-
src/entry - The client and server entry points, which call on src/components/root.tsx to isomorphically render the React chain in both environments.
-
src/global - A good place for anything that's used through your entire app, like global styles. I've started you off with a styles.ts that sets globally inlined Emotion CSS, as well as pulls in a global
.scss
file -- to show you how both types of CSS work. -
src/lib - Internal libraries/helpers. There's an apollo.ts which builds a universal Apollo Client. Plus, Koa middleware to handle hot-code reloading in development and some other Webpack helpers.
-
src/queries - Your GraphQL queries. There's just one by default - for pulling the top stories from Hacker News to display in the example component.
-
src/runner - Development and production runners that spawn the Webpack build process in each environment.
-
src/views - View components that fall outside of the usual React component chain, for use on the server. In here, ssr.tsx takes care of rendering the root HTML that's sent down the wire to the client. Note this is also a React component - your whole app will render as React! - and static.html serves as a template for rendering a client-side SPA. Update it as needed.
-
src/webpack - The Webpack 4 configuration files that do the heavy lifting to transform our Typescript code, images and CSS into optimised and minified assets that wind up in the
dist
folder at the root. Handles both the client and server environments.
You'll also find some other useful goodies in the root...
-
.env - Change your
GRAPHQL
server endpoint,WS_SUBSCRIPTIONS=1
for built-in WebSocket support,HOST
if you want to bind the server to something other than localhost, andLOCAL_STORAGE_KEY
to set the root key for saving MobX state locally in the client for automatic re-loading in a later session. -
.nvmrc - Specify your preferred Node.js version, for use with NVM and used by many continuous deployment tools. Defaults to v12.2.0
-
codegen.yml - Settings for GraphQL Code Generator (which you can run with
npm run gen:graphql
to generate types/HOCs based on your GraphQL queries/mutations.) -
netlify.toml - Build instructions for fast Netlify deployments. Tip: To quickly deploy a demo ReactQL app, click here.
-
types - Some basic types that allow you to import fonts, images, CSS/SASS/LESS files, and allow use of the global
SERVER
boolean andGRAPHQL
endpoint data in your IDE. -
Typescript configuration via tsconfig.json
-
A sample multi-build Dockerfile based on Node 11.8 and Alpine, for quickly deploying your code base to production.
Follow @reactql for updates
Get the latest updates by following us on Twitter: https://twitter.com/reactql
New to GraphQL? Need help?
Join the ReactQL slack channel here.
Watch my free 45 minute YouTube video, for a live coding walk-through of putting together a GraphQL server with a database. Learn how to write queries, mutations and handle nested/related data.
Hire me
I'm a full-stack developer with 20+ years experience. As well as 9 years hands-on dev with Node.js, I'm fluent in Python, Go, SQL and NoSQL. I specialise in building robust, scalable products from scratch, and helping you deploy fast.
If you're looking for a senior developer who can help you get your product out the door quickly, reach me at lee@leebenson.com. I'm occasionally available to take on remote contracts when I'm not working on my own projects.
Top Related Projects
Set up a modern web app by running one command.
The React Framework
The best React-based framework with performance, scalability and security built in.
Develop. Preview. Ship.
The App Framework for Startups
Build Better Websites. Create modern, resilient user experiences with web fundamentals.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot