{"id":22688746,"url":"https://github.com/k2052/vanilla-hn","last_synced_at":"2025-04-12T21:52:11.132Z","repository":{"id":23582017,"uuid":"99380932","full_name":"k2052/vanilla-hn","owner":"k2052","description":"A Hacker News Reader in Vanilla JavaScript","archived":false,"fork":false,"pushed_at":"2025-04-09T20:17:05.000Z","size":5752,"stargazers_count":34,"open_issues_count":0,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-12T21:52:05.769Z","etag":null,"topics":["es6","hacker-news","javascript"],"latest_commit_sha":null,"homepage":"https://k2052.github.io/vanilla-hn","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/k2052.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2017-08-04T21:30:08.000Z","updated_at":"2025-04-09T20:17:02.000Z","dependencies_parsed_at":"2023-02-13T07:00:42.779Z","dependency_job_id":"992070ad-96cc-47d1-9a38-491368ef499f","html_url":"https://github.com/k2052/vanilla-hn","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/k2052%2Fvanilla-hn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/k2052%2Fvanilla-hn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/k2052%2Fvanilla-hn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/k2052%2Fvanilla-hn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/k2052","download_url":"https://codeload.github.com/k2052/vanilla-hn/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248637833,"owners_count":21137538,"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","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":["es6","hacker-news","javascript"],"created_at":"2024-12-10T00:15:48.030Z","updated_at":"2025-04-12T21:52:11.107Z","avatar_url":"https://github.com/k2052.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vanilla JavaScript Hacker News\n\nThis is a Hacker News client in plain vanilla JavaScript. It depends on zero frontend frameworks. There is no React, no Vue, no Ember, just modern JavaScript.\n\n- Uses zero frameworks on the client side\n- Fully universal with server side rendering and state hydration\n- An architecture much like a modern React stack\n\nIt takes many modern web-dev ideas and uses non-framework solutions to implement them. For JSX like templates, it uses template strings. For components, it uses functions that return template strings. For data-flow and effects, it uses async generators. For routing, it uses a simple switchPath function that matches a route to an async function that returns a component. The architecture is designed to reveal the problems that frameworks like React were built to solve.  \n\n*Note*: This is meant as a learning example and I highly recommend you use a framework in real world applications.\n\n## Installation\n\nYou can install all the dependencies by running:\n\n```sh\n$ yarn install\n```\n\n## Usage\n\n### Running The App\n\nYou can start up a dev server by running:\n\n```sh\n$ yarn run dev\n```\n\nThis will boot up [webpack-dev-server](https://webpack.js.org/configuration/dev-server/) on port 9000. There is no hot-reloading but the page will refresh when there are changes.\n\nYou can start the production server by running start:\n\n```sh\n$ yarn run start\n```\n\n### Building\n\nYou can build the dev version of the app by running:\n\n```sh\n$ yarn run webpack\n```\n\nYou can build the client by running\n\n```sh\n$ yarn run build.client\n```\n\nTo build the server run:\n\n```sh\n$ yarn run build.server\n```\n\n### Tests\n\nTests are done using [Chai](http://chaijs.com) and [Jest](https://facebook.github.io/jest). You can run them like this:\n\n```sh\n$ yarn run test\n```\n\n*Note*: Run `$ yarn run build.client` the first time you run the tests or the test that tests assets are served will fail.\n\nTo get coverage details run:\n\n```sh\n$ yarn run coverage\n```\n\n### Deployment\n\nThe app is designed to be static and once built to dist it can be deployed pretty much anywhere. It also comes with a SSR version that can be deployed to any node host.\n\n#### Deploying to Zeit\n\nTo deploy to Zeit run:\n\n```sh\n$ yarn run deploy.zeit\n```\n\n#### Deploying to GitHub\n\nTo deploy to GitHub run:\n\n```sh\n$ yarn run deploy.gh\n```\n\n## Architecture\n\nThe app is made up of components, events, and sagas.\n\nThe [components](https://github.com/k2052/vanilla-hn/blob/master/docs/architecture/Components.md) are functions that take state and return a string representation of that state. They are a lot like React components except they use template strings instead of JSX and they don't use a virtual DOM. Instead of a virtual DOM we use innerHTML and keep track of what state has changed and the corresponding component for that state.\n\nThe [events](https://github.com/k2052/vanilla-hn/blob/master/docs/architecture/Events.md) are a lot like Flux. They are plain objects that get passed into a [Store](https://github.com/k2052/vanilla-hn/blob/master/docs/architecture/Store.md); the store dispatches the events to Sagas to be processed and finally new state is generated which causes re-renders.\n\n[Sagas](https://github.com/k2052/vanilla-hn/blob/master/docs/architecture/Sagas.md) are async generators that respond to actions by yielding [effects](https://github.com/k2052/vanilla-hn/blob/master/docs/architecture/Effects.md). Effects are where all the bad stuff is handled. They are where we do stuff that manipulates the state and the DOM.\n\nYou can read more about the app's architecture in the [docs](https://github.com/k2052/vanilla-hn/blob/master/docs/README.md)\n\n## Known Issues\n\n- Routes with the dev server are not universal i.e you can't bookmark a story and return to it -- a refresh returns a 404.\n- Needs to hashes for pages (e.g #ask) on the static version so URLS like /ask don't 404\n\n## Future Plans\n\n- Improved loading indicators\n- Login/Signup\n- hot-reload\n- Replace Koa usage with plain node http servers\n\n## Credits\n\nThe design of this is a direct port of [next-news](https://next-news.now.sh)\n\n## License\n\nLicensed under MIT\n\n## Hire Me\n\nI'm looking for work! Drop me a line [k@2052.me](mailto:k@2052.me) if you are hiring.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fk2052%2Fvanilla-hn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fk2052%2Fvanilla-hn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fk2052%2Fvanilla-hn/lists"}