{"id":16193872,"url":"https://github.com/wwwy3y3/coren","last_synced_at":"2025-10-28T16:21:13.596Z","repository":{"id":57209454,"uuid":"92904332","full_name":"wwwy3y3/coren","owner":"wwwy3y3","description":"React offline server-rendered framework","archived":false,"fork":false,"pushed_at":"2018-03-20T11:08:40.000Z","size":1239,"stargazers_count":103,"open_issues_count":2,"forks_count":2,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-07-10T00:18:08.465Z","etag":null,"topics":["react","server-side-rendering","ssr"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wwwy3y3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"Contributing.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-31T04:29:53.000Z","updated_at":"2021-05-20T19:37:21.000Z","dependencies_parsed_at":"2022-09-18T01:55:51.011Z","dependency_job_id":null,"html_url":"https://github.com/wwwy3y3/coren","commit_stats":null,"previous_names":["canner/render"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/wwwy3y3/coren","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wwwy3y3%2Fcoren","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wwwy3y3%2Fcoren/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wwwy3y3%2Fcoren/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wwwy3y3%2Fcoren/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wwwy3y3","download_url":"https://codeload.github.com/wwwy3y3/coren/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wwwy3y3%2Fcoren/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267763912,"owners_count":24140827,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-29T02:00:12.549Z","response_time":2574,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["react","server-side-rendering","ssr"],"created_at":"2024-10-10T08:16:53.731Z","updated_at":"2025-10-28T16:21:13.484Z","avatar_url":"https://github.com/wwwy3y3.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# Coren\n\n\u003e React Pluggable server-rendered framework\n\n[![npm Version](https://img.shields.io/npm/v/coren.svg?style=flat-square)](https://www.npmjs.org/package/coren)[](https://travis-ci.org/Canner/coren)\n![Build Status](https://travis-ci.org/Canner/coren.svg?branch=master)\n\n## Presentation\n\nJSDC 2017: [React server-side render nightmare gone](https://speakerdeck.com/wwwy3y3/react-server-side-render-nightmare-gone)\n\n## Concept\n**React SSR is super HARD!!!!!**\n\nReact developers constantly dealing with issues below:\n* Some modules require additional Provider wrapped outside during SSR, e.g, `react-router`, `react-redux`, `react-intl`...\n* For performance issue (or you're not using nodejs as serverside language), you ended up creating a nodejs server **JUST FOR SSR**\n* Some 3rd party modules are using `document`, `window`, so SSR will fail, and you need a fallback.\n\nDealing with these issues just for SSR  may be concerned not worthy, so most developers will just give up.\n\nNow, `Coren` help you deal with these issues.\n\n# Features\n\n## Easy to use\n`Coren` use decorators to serverside render your component\n\n``` js\n@head({title: \"home\", description: \"home description\"})\n@route('/')\n@ssr\nexport default class Root extends Component {\n  //...\n}\n```\n\n## No limit on modules\nThere's no limit on what modules or plugins you can use, `react-router`, `reactCssModule`, `scss-loader`, `react-intl` etc...\n\n## Integrate well with commonly used modules\n``` js\n// react-redux\n@reactRedux({reducer})\n\n// react-router and react-redux\n@reactRouterRedux({reducer})\n\n// react-router, react-redux, react-intl with one line\n@reactRouterReduxIntl({reducer})\n```\n\n## Prerender partial pages\nCoren prerender your components offline, with initial redux state you provide, you may respond with data fetched from DB on server.\n![prerender](https://i.imgur.com/saobnW7.png)\n\n``` js\n// on express server\napp.get('/', function(req, res) {\n  return db.fetchUsers(users =\u003e\n    // insert users to redux preloadedState\n    res.setPreloadedState({users}).sendCoren('/')\n  );\n});\n```\n\n# Example repo\nThere are some complete example repos you can make use of.\n* [use with CSS](https://github.com/Canner/coren/tree/master/examples/withCss)\n* [use with SCSS](https://github.com/Canner/coren/tree/master/examples/withSCSS)\n* [use with ReactCSSModule](https://github.com/Canner/coren/tree/master/examples/withReactCSSModules)\n* [use with Redux](https://github.com/Canner/coren/tree/master/examples/withRedux)\n* [use with ReactRouter and Redux](https://github.com/Canner/coren/tree/master/examples/withReactRouterRedux)\n* [use with ReactRouter, Redux and React-intl](https://github.com/Canner/coren/tree/master/examples/withReactRouterReduxIntl)\n\n# How to use Coren?\nCoren uses `decorator` to wrap component to make server side render work. Each decorator can define its `lifecycle`, and coren will execute them at each lifecycle.\n\nWe're going to use [css example](https://github.com/Canner/coren/tree/master/examples/withCSS) to explain.\n\n## Coren Config\nTake a look at `coren.config.js` file\n* entry: entry will tell coren what components are going to be server-side renderes\n``` js\nentry: {\n  index: './client/Content.js'\n}\n```\n* ssrWebpack: webpack settings for server-side process to generate commonjs version of your components\n``` js\nssrWebpack: {\n  plugins: [\n    new webpack.BannerPlugin('This file is created by coren. Built time: ' + new Date()),\n    extractCSS\n  ],\n  module: {\n    rules: [\n      {\n        test: /\\.css$/,\n        use: extractCSS.extract([\"css-loader?minimize\"])\n      }\n    ]\n  }\n}\n```\n* assetsHost: assetsHost tell coren what links to be inserted to HTML, say on local development, you might want the js links to request to devServer.\n``` js\nassetsHost: (env, absolutePath = '') =\u003e {\n  const rel = path.relative(`${__dirname}/public/dist/`, absolutePath);\n  switch (env) {\n    case 'production':\n      return `/dist/${rel}`;\n    case 'development':\n      return `http://localhost:5556/dist/${rel}`;\n    default:\n      return false;\n  }\n}\n```\n\n## Decorators\nTake a look at `client/Content.js` file\n``` js\nimport React, {Component} from 'react';\nimport {ssr, route, head} from 'coren';\nimport './style.css';\n\n@head({title: \"home\", description: \"home description\"})\n@route('/')\n@ssr\nexport default class Root extends Component {\n  render() {\n    //...\n  }\n}\n```\n\n* `@head` decorator tell coren to insert head elements\n* `@route('/')` tell coren to prerender with `/` url on this component \n* `@ssr` to tell coren this component is required to be SSR\n\n## Wrap your webpack with corenWebpack\nWe handle the required SSR webpack settings for you.\n\n``` js\nconst CorenWebpack = require('coren/lib/client/webpack');\n\nconst config = new CorenWebpack(__dirname, {\n  // write original webpack setting\n});\n\nmodule.exports = config.output();\n```\n\n## Last Step: use coren middleware on server\n``` js\nconst app = express();\nconst coren = require('coren/lib/server/coren-middleware');\napp.use(coren(path.resolve(__dirname, '../')));\n// serve the js, css files webpack generate\napp.use(express.static(path.resolve(__dirname, '../public')));\n\napp.get('/', function(req, res) {\n  return res.sendCoren('/');\n});\n```\n\nSo it's very easy to use coren and integrate in your current project.\n\n**coren build flow :**\n\n```\n+----------------------+   +--------------------+   +----------------+\n|                      |   |                    |   |                |\n| read coren.config.js +---\u003e do coren lifecycle +---\u003e build ssr html |\n|                      |   |                    |   |                |\n+----------------------+   +--------------------+   +----------------+\n```\n\nLet' recap what we do to make coren work:\n\n* add `coren.config.js`\n* use `decorator` to wrap ssr component\n* use `CorenWebpack` at webpack.config.js\n* use coren middleware to host the file\n\nNext, you can look at the documentation and understand how coren works internally.\n\n# API Documentation\n## coren.config.js\n\n`coren.config.js` is config file to make coren run correctly.\n\nConfig key:\n\n- entry `(required)`\n- assetsHost `(required)`\n- ssrWebpack `(optional)`\n- prepareContext `(optional)`\n\n### entry\n\n\u003e JS entry point you want to build (like webpack entry)\n\nThis entry will be used in `server side webpack`.\n\n- type: Object\n\n**example:** \n\n```javascript\n{\n  entry: {\n    index: './index.js'\n  }\n}\n```\n\n### assetsHost\n\n\u003e host path in the different environment.\n\u003e\n\u003e Because coren will automatically append static file link to ssr result, you need to provide the corresponding static link at different environment.\n\n- type: Function(env: String, absolutePath: String)\n  - Provide `production`, `development`, `pre-production` env cases return value.\n- return: String\n\n\n\n**example:**\n\n```javascript\n{\n  assetsHost: (env, absolutePath = '') =\u003e {\n    const rel = path.relative(`${__dirname}/dist/`, absolutePath);\n    switch (env) {\n      case 'production':\n        return `/dist/${rel}`; // example: /dist/index.js\n      case 'development':\n      case 'pre-production':\n        return `http://localhost:9393/dist/${rel}`;\n      default:\n        return false;\n    }\n  }\n}\n```\n\n### ssrWebpack\n\n\u003e server side render webpack setting\n\n- type: Object\n\nThis webpack setting will be used during server side render. The configuration will be passed to `webpack` internally.\n\nJust put any webpack configurations in here except `entry`.\n\n**example:**\n\n```javascript\n{\n   ssrWebpack: {\n    plugins: [\n      new webpack.BannerPlugin('This file is created by coren. Built time: ' + new Date())\n    ]\n  }\n}\n```\n\n### prepareContext\n\n\u003e Prepare `global` ssr variable.\n\u003e\n\u003e In some case, you may want to load data before doing ssr. You can add any variable you want and coren will save it in `context`.\n\n- type: Function\n- return: Promise\n\n**example:**\n\n```javascript\n{\n  prepareContext: function() {\n    return Promise.resolve({db: {auth: true}});\n  }\n}\n```\n\n## webpack configuration\n\nTo make server side render work, coren will do some required process when you build client side webpack. You need to extend `CorenWebpack` to make it work.\n\n**example: webpack.config.dev.js**\n\n```javascript\nconst CorenWebpack = require('coren/lib/client/webpack');\n\nconst config = new CorenWebpack(__dirname, {\n  // write original webpack setting\n});\n\nmodule.exports = config.output();\n```\n\nThe only thing you need to do is `new CorenWebpack` and put all your original webpack setting at the second parameter. \n\n\n\n## express\n\nWhen use coren, you don't need to use other template engine like `pug`. The html file is built by coren. We will help you to append the proper static file link \u0026 `\u003chead/\u003e` config.\n\nTo make it work, coren provide a coren express middleware. This middleware will automatically load the proper html based on entry name. It also provide some basic api to help you alter the html return.\n\n**example:**\n\n```javascript\nconst express = require('express');\nconst path = require('path');\nconst app = express();\nconst coren = require('coren/lib/server/coren-middleware');\napp.use(coren(path.resolve(__dirname, '../')));\napp.use(express.static(path.resolve(__dirname, '../public')));\n\napp.get('/*', function(req, res) {\n  return res.setPreloadedState({auth: true}).sendCoren('/');\n});\n\napp.listen(9393, 'localhost', function(err) {\n  if (err) {\n    console.log(err);\n    return;\n  }\n\n  console.log('Listening at http://localhost:9393');\n});\n```\n\n## Express Integration - coren middleware\n\nFrom above example, in our express server, just include `coren middleware` and then ssr is done.\n\nIt means that we don't need to require any react related code and coren module. So your server become cleaner.\n\n## Middleware API\n\n### res.setHead(Function($head: cheerio instance))\n\nsetHead api let you manipulate the content in `\u003chead\u003e\u003c/head\u003e`.\n\nYou can reference `cheerio` to know the supported api.\n\n**example:**\n\n```javascript\napp.get('/', function(req, res) {\n  res.setHead(function($head) {\n    $head.append('\u003cscript\u003ealert(\"coren!\")');\n  });\n  return res.sendCoren('index');\n});\n```\n\n### res.setPreloadedState(Object)\n\nmerge preloadedState content.\n\nWith this api, the status of your app can be controlled by server.\n\n**example:**\n\n```javascript\napp.get('/', function(req, res) {\n  res.setPreloadedState({auth: false, user: 'john'});\n  return res.sendCoren('/');\n});\n```\n\n### res.sendCoren(`url`)\n\nsendCoren api is used to send proper prerendered html file with url provided in parameter. \n\nSo, if you want to respond index, you can write: `res.sendCoren('/')`\n\n## Coren decorator lifecycle\n![lifecycle](https://i.imgur.com/j6AZal5.png)\n\n\n## Integrate with current project\n\nThough coren is unstable now, in our concept, it's very easy to integrate coren to your current project.\n\nJust follow these steps:\n\n1. write `coren.config.js`\n2. Use `new CorenWebpack` to extend webpack config\n3. add `coren decorator` at your component\n4. add `coren middleware` at express server\n5. start webpack server\n6. after webpack is built, `npm run coren-dev` ( or `coren dev`)\n7. start express\n\n# Limitation\n\n- Based on webpack: coren strongly count on webpack, currently it doesn't support other tools like `rollup`, `browserify`.\n- Because coren is server side render framework, there are some modules that don't support `isomorphic` environment. For these modules, that may break the ssr.\n\n# License\nApache-2.0 [@Canner](https://github.com/canner)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwwwy3y3%2Fcoren","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwwwy3y3%2Fcoren","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwwwy3y3%2Fcoren/lists"}