{"id":17044770,"url":"https://github.com/keredson/bottle-react","last_synced_at":"2025-07-23T06:03:55.916Z","repository":{"id":57416129,"uuid":"74413701","full_name":"keredson/bottle-react","owner":"keredson","description":"A microframework for Bottle+React (or Flask+React) projects.","archived":false,"fork":false,"pushed_at":"2019-09-26T04:03:13.000Z","size":236,"stargazers_count":91,"open_issues_count":6,"forks_count":17,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-07-03T14:09:45.528Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/keredson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-11-21T23:03:55.000Z","updated_at":"2025-03-06T15:51:27.000Z","dependencies_parsed_at":"2022-08-23T17:00:20.627Z","dependency_job_id":null,"html_url":"https://github.com/keredson/bottle-react","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/keredson/bottle-react","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keredson%2Fbottle-react","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keredson%2Fbottle-react/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keredson%2Fbottle-react/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keredson%2Fbottle-react/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/keredson","download_url":"https://codeload.github.com/keredson/bottle-react/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keredson%2Fbottle-react/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266626115,"owners_count":23958344,"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-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"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":[],"created_at":"2024-10-14T09:35:28.173Z","updated_at":"2025-07-23T06:03:55.887Z","avatar_url":"https://github.com/keredson.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"![image](https://user-images.githubusercontent.com/2049665/34214474-37c285c6-e568-11e7-963e-407533d01d80.png)\n\n# Bottle-React\n\n***NOW SUPPORTS FLASK!*** See [examples/hello_world/run_flask.py](examples/hello_world/run_flask.py).\n\n## Description\nThis library allows you to return react components from either Bottle or Flask.  Originally created for https://www.hvst.com/.\n\n## Example (Hello World)\n\nAssume you have a normal JSX file `hello_world.jsx`:\n```js\nvar HelloWorld = React.createClass({\n  render: function() {\n    return (\n      \u003cdiv className='hello_world'\u003e\n        \u003ch1\u003eHello {this.props.name}!\u003c/h1\u003e\n        \u003cdiv\u003e\n          Thanks for trying bottle-react!\n        \u003c/div\u003e\n      \u003c/div\u003e\n    );\n  }\n})\nbottlereact._register('HelloWorld', HelloWorld)\n```\n\nAnd some python code:\n```python\napp = bottle.Bottle()\nbr = BottleReact(app)\n\n@app.get('/')\ndef root():\n  return br.render_html(\n    br.HelloWorld({'name':'World'})\n  )\n```\n\nWhen your route is called the react component will be rendered.  See [examples/hello_world](examples/hello_world) for details.\n\n## Principles\n\nWhy did we develop this?  We had several goals:\n\n- [x] Don't cross-compile javascript during development.\n\nCompiling with `webpack` is too slow for non-trivial applications.  (One of the niceties about web developement it `alt-Tab`/`ctrl-R` to see your changes.)  And it causes too many subtle bugs between dev and prod that waste developer resources.\n\n- [x] Don't merge all javascript into one ginormous bundle.\n\nMaking your user download a 1.5Mb `kitchensink.min.js` every deployment is horrible.  And 99% of it isn't used on most pages.  Loading 40kb total from multiple resources with HTTP keep-alive takes just a few ms per file and is much faster in practice.\n\n- [x] React components should be composable from Python.\n\nA lot of our routes look like this:\n\n```python\n@app.get('/something')\ndef something():\n  user = bottle.request.current_user\n  return br.render_html(\n    br.HvstApp({'user':user.to_dict()}, [\n      br.HelloWorld({'name':user.name}),\n    ])\n  )\n```\n\nThe React component `HvstApp` (which renders the title bar and left nav) is taking two parameters.  The first is a `dict` that will be passed as the JSON props to the React component.  The second is a `list` that will become the children.  This list can (and usually does) contain other React components.\n\n\n## Install\n```python\nsudo pip install bottle-react\n```\n\n## NGINX Integration\nBy default (in production mode) `bottle-react` writes to `/tmp/bottlereact/hashed-assets/`.  To make NGINX serve these files directly, use the following:\n\n```\n  location ^~ /__br_assets__/ {\n    alias /tmp/bottlereact/hashed-assets/;\n    expires max;\n  }\n```\n\n## Server Side Rendering\nTo use server side rendering, please install the npm package [`node-jsdom`](https://www.npmjs.com/package/node-jsdom) with:\n\n```\n$ sudo npm install -g node-jsdom\n```\n\nThen pass either `True` or a callable into the `render_server` parameter.  For example:\n\n```python\ndef render_server():\n  ua = bottle.request.environ.get('HTTP_USER_AGENT')\n  return util.is_bot(ua)\n```\n\nBTW...  Before enabling it for everyone, run some benchmarks.  We find that it has very little impact on total page load time, at a considerable CPU expense and double the downloaded HTML size.  So we only do it for search bots (as you can see in the example above).\n\nYou will also likely have to shim some missing browser features.  At minimum, React likes to put itself under `window` when run inside `nodejs`, so we have:\n\n```javascript\n// react in nodejs will put itself under window\nif(typeof React == 'undefined') {\n  React = window.React;\n}\n```\n\nIn our `application.js`, since all our code expects it to be a global.  Likewise, for things `node-jsdom` hasn't yet implemented, you'll likely find a few checks are needed, like:\n```javascript\nif (typeof DOMParser=='undefined') {\n  // i guess we're not using DOMParser inside nodejs...\n}\n```\n\n\n## Documentation\n\nSee the [full documentation](DOCS.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeredson%2Fbottle-react","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkeredson%2Fbottle-react","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeredson%2Fbottle-react/lists"}