{"id":15723466,"url":"https://github.com/ewrogers/hyper-calendar","last_synced_at":"2025-05-13T04:01:33.125Z","repository":{"id":193744128,"uuid":"689391502","full_name":"ewrogers/hyper-calendar","owner":"ewrogers","description":"Hypermedia-driven application using HTMX + Hono + Bun","archived":false,"fork":false,"pushed_at":"2023-11-04T18:49:54.000Z","size":429,"stargazers_count":19,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-20T22:32:37.076Z","etag":null,"topics":["bun","css","hono","html","htmx","hypermedia","hyperscript","javascript","nodejs","ssr","tsx","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/ewrogers.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,"publiccode":null,"codemeta":null}},"created_at":"2023-09-09T16:53:07.000Z","updated_at":"2024-11-13T22:13:48.000Z","dependencies_parsed_at":"2023-09-09T19:27:29.054Z","dependency_job_id":"e232675b-09c8-4f94-ac78-13c0362dd5ea","html_url":"https://github.com/ewrogers/hyper-calendar","commit_stats":null,"previous_names":["ewrogers/hda-calendar","ewrogers/hyper-calendar"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ewrogers%2Fhyper-calendar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ewrogers%2Fhyper-calendar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ewrogers%2Fhyper-calendar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ewrogers%2Fhyper-calendar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ewrogers","download_url":"https://codeload.github.com/ewrogers/hyper-calendar/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253870865,"owners_count":21976613,"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":["bun","css","hono","html","htmx","hypermedia","hyperscript","javascript","nodejs","ssr","tsx","typescript"],"created_at":"2024-10-03T22:11:49.679Z","updated_at":"2025-05-13T04:01:32.529Z","avatar_url":"https://github.com/ewrogers.png","language":"TypeScript","readme":"# hyper-calendar\n\nA proof-of-concept [Hypermedia](https://en.wikipedia.org/wiki/Hypermedia)-driven calendar application.\n\nIt is based on `en-US` locale (12-hour time) but could easily be adapted to other locales.\n\nNo additional JavaScript or \"SPA\" frontend is required!\nAll interactivity is handled by the server and [HTMX](https://htmx.org) + [Hyperscript](https://hyperscript.org/).\n\nIt is greatly inspired by the book [Hypermedia Systems](https://hypermedia.systems/), which is an amazing read for building Hypermedia-driven applications.\n\n![image](./screenshots/calendar.png)\n\n**Disclaimer:** I am not a designer, so the UI is very basic and minimal. My CSS is probably awful, but it works.\n\n## Tech Stack\n\n- [HTMX](https://htmx.org)\n- [Hyperscript](https://hyperscript.org/)\n- JSX + CSS\n- [Hono](https://hono.dev/)\n- [Bun](https://bun.sh)\n- [SQLite](https://www.sqlite.org/index.html)\n\n**NOTE:** This library leverages Bun and Hono's native support for [JSX](https://bun.sh/docs/runtime/jsx), no need for React or another SPA frameworks.\n\n## Requirements\n\nYou just need Git + Bun:\n\n```bash\ncurl -fsSL https://bun.sh/install | bash\n```\n\n## Getting Started\n\nIt is as easy as cloning the repository and running the application:\n\n```bash\ngit clone https://github.com/ewrogers/hyper-calendar\ncd hyper-calendar\ncp .env.example .env\n\nbun install\nbun run seed\n\nbun run dev\n```\n\nThen you can view the application at [http://localhost:3000](http://localhost:3000).\n\n**NOTE**: You only need to run `bun seed` once, as it will create the database and seed it with some example data.\n\n## Why this stack?\n\nThe main focus of this stack is minimal, [low complexity](https://grugbrain.dev/) with high performance.\nThat means selecting the right tool for the job, and not adding unnecessary dependencies.\nMost of these libraries are also very small, and have little-to-no dependencies themselves.\n\nThe better question might be *\"Why do we need React?\"* (or similar frameworks) in the first place?\n\nPerhaps you are old enough to remember the early days of the internet and Web 1.0.\nYou would click a link, and the browser would fetch a new page from the server and render it.\n\nNo need for additional front-ends, megabytes of JavaScript code, and complex state management. Just simple HTML and HTTP.\nWhat needed to be displayed was dictated by the server, and the browser would render it accordingly.\n\nSo why exactly did we move away from this model? Why did we need to add all this complexity? Interactivity and immersion.\n\nWhat if I told you we could have the best of both worlds?\n\n### HTMX\n\nWhat if we could have Web 1.0 simplicity with Web 2.0 interactivity? That is the goal of [HTMX](https://htmx.org).\n\nHTMX is a small JavaScript library that allows you to add interactivity to your HTML pages with minimal effort\nand minimal file size. It's a mere **14KB** minified and gzipped!\n\nInstead of serving a JSON API and a front-end that has to consume it, manage state, and then update the DOM\nwe can simply use HTML and HTTP to do the same thing in the browser.\n\nIt will even handle things like CSS transitions for you, so you still get that immersive experience without the bloat.\n\nOh and you don't need to worry about versioning an API, deploying breaking changes, or any of that nonsense.\nJust update your HTML and you're done!\n\n### HyperScript\n\nUndoubtedly, there will be times when you need to mutate the DOM in some way, usually for user interaction.\nEven with Web 1.0, you would have to write some JavaScript to do this (or use a library like jQuery).\n\nThe companion library to HTMX is [HyperScript](https://hyperscript.org/), which is a small JavaScript library\nthat allows you to create dynamic behaviors in a very simple and declarative way in-line with your HTML.\n\nFor those familiar with [HyperCard](https://hypercard.org/) and [AppleScript](https://en.wikipedia.org/wiki/AppleScript),\nthis will feel very familiar and refreshing.\n\nOne of the biggest advantages of HTMX paired with HyperScript is everything is declared in HTML itself.\nThis promotes a very clear [locality of behavior](https://htmx.org/essays/locality-of-behaviour/),\nmaking it easy to reason about and debug without having to jump around between multiple files.\n\nIt even has an [in-browser debugger](https://hyperscript.org/hdb/).\n\n### Hono\n\nUsing Hypermedia we still need an HTTP server to handle requests from the client and return new application state as HTML.\n\nThis decoupling means you can use any language or framework you want, as long as it can return HTML.\nThis is also known as the [HOWL stack](https://htmx.org/essays/hypermedia-on-whatever-youd-like/).\n\nI have chosen [Hono](https://hono.dev/) which is a lightweight, ultrafast HTTP server, written in TypeScript.\nIt also supports JSX out of the box, which will be our templating engine.\n\nThis is also a good example of how JavaScript/TypeScript does not **have** to be heavy and slow.\n\n**Yes, this is server-side rendering (SSR)!**\n\n### JSX\n\nWe will be returning HTML, so we need a way to generate it.\nJSX is a powerful way to do this, and you don't need React in order to use it!\n\nWe can still structure our project using components and embedded them in our HTML templates.\nThis is a great way to keep things organized and maintainable.\n\nFor styling, I have gone with plain CSS for simplicity.\nAlternatively, you could use something like [Tailwind](https://tailwindcss.com/) if you wanted to.\n\n### Bun\n\nTypeScript means we need a runtime engine. [Bun](https://bun.sh/) has hit v1.0 stable release and is a wonderful all-in-one toolkit for JavaScript.\n\nNot only is it an insanely fast runtime, it provides a wonderful refined API along with great built-in tooling for stuff like tests, package management, and bundling.\n\nIt also supports TypeScript and JSX without the need for any additional ceremony or dependencies. It's incredibly refreshing to be able to create a modern TypeScript project with only a couple of files.\n\n**NOTE:** Bun's TypeScript support is runtime-only, so it is recommended you use a [language server](https://github.com/typescript-language-server/typescript-language-server) (LSP) for static-type checking.\n\n### SQL\n\nNeeding to persist data, I have gone with SQL. It's simple, well-known, and has amazing support throughout nearly every eco-system.\n\n[Bun supports SQLite out of the box](https://bun.sh/docs/api/sqlite), which makes local development both easy and consistent. When it's time to go to production, just change your connection string and it should Just Work™.\n\nThis application intentionally avoids using an ORM, as plain SQL queries are much simpler and efficient than hoping your ORM does what you want it to do.\n\nAgain, minimalism and reduced complexity.\n\n## Code Style\n\nThis project uses `prettier` and `lint-staged` to ensure the code style is preserved.\n\nYou could add additional linting like `eslint` but I did not want to add more dependencies and clutter to this example.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fewrogers%2Fhyper-calendar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fewrogers%2Fhyper-calendar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fewrogers%2Fhyper-calendar/lists"}