{"id":23418551,"url":"https://github.com/rustshop/htmx-sorta","last_synced_at":"2025-04-12T11:33:17.720Z","repository":{"id":193201522,"uuid":"686557239","full_name":"rustshop/htmx-sorta","owner":"rustshop","description":"Rust + htmx + tailwind + nix + redb  demo web app","archived":false,"fork":false,"pushed_at":"2024-03-24T04:35:36.000Z","size":140,"stargazers_count":72,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-06T17:11:18.453Z","etag":null,"topics":["astra","htmx","redb","rust","tailwind","twind","web"],"latest_commit_sha":null,"homepage":"","language":"Rust","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/rustshop.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-03T07:29:21.000Z","updated_at":"2025-03-31T13:11:25.000Z","dependencies_parsed_at":"2023-09-18T04:41:45.390Z","dependency_job_id":"f4ae7ae3-b41e-428c-978b-6826d99f1165","html_url":"https://github.com/rustshop/htmx-sorta","commit_stats":null,"previous_names":["dpc/htmx-sorta","rustshop/htmx-sorta"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustshop%2Fhtmx-sorta","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustshop%2Fhtmx-sorta/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustshop%2Fhtmx-sorta/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustshop%2Fhtmx-sorta/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rustshop","download_url":"https://codeload.github.com/rustshop/htmx-sorta/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248560164,"owners_count":21124604,"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":["astra","htmx","redb","rust","tailwind","twind","web"],"created_at":"2024-12-23T00:20:18.829Z","updated_at":"2025-04-12T11:33:17.693Z","avatar_url":"https://github.com/rustshop.png","language":"Rust","readme":"# htmx sorta\n\nA demo project where I learn and play with my \"Rust web stack\":\n\n* Rust\n* Nix flakes for building and dev shell\n* [redb](https://github.com/cberner/redb) Rust local key-value store database\n* [astra](https://github.com/ibraheemdev/astra) Rust web server library\n* [maud](https://github.com/lambda-fairy/maud) Rust html templating library\n* [htmx](https://htmx.org/) for dynamic html frontend\n* [tailwind](https://tailwindcss.com/)\n\nIn essence it's a TODO app, and looks like this (click for a video):\n\n[![Video Preview](https://i.imgur.com/Q8RfOzf.png)](https://i.imgur.com/ctz2bcJ.mp4)\n\nNote: server response slowness is simulated to help improve the UX. The imgur \"optimized\"\nthe video and now it's slow and laggy, but I have no energy to fight with\nit right now. In reality things are working just fine.\n\nSome of the features: persistent ordered list, with drag'n'drop UX, responsive html,\ngraceful offline handling, rate limiting.\n\nI think it might be source of inspiration and example for people that would\nlike to use a similar set of tools for their own projects.\n\n## Running\n\nIf you're a Nix flake user you can run `nix run github:dpc/htmx-sorta`. Otherwise,\nproceed like with any other Rust project.\n\n## About the stack\n\nI like things simple, small and to the point. Also - it's a bit of a research project,\nso I'm not afraid to try out things that are not most popular and trendy.\n\nI'd like to avoid using async Rust, because it's immature and PITA\nto use, while blocking IO is perfectly sufficient. That's why I use `astra`,\nwhich is very promising blocking IO Rust web framework/library.\n\nI don't want any C-binding based dependencies, and that's why I'm using `redb`,\nwhich is very promising and lean key value store, in a similar category as e.g. RocksDB.\n\nI don't like DSL, especially looking like combination of Python and HTML, so\n`maud` is my favourite HTML framework. Again - fast, lean, to the point.\n\nI'm tired of all the SPAs that are slow heavy and barely work. I'm more of a backend\ndeveloper than a frontend developer. I think HTMX is the direction that Web\nshould have taken long time ago, instead of betting everything on Javascript. I'm not afraid of\nadding JS to the code, but it shouldn't be for UX niceness and not the tail wagging\nthe dog.\n\nI'm not much of a designer or a web developer, but I've done some web projects\nover last two decades, and I wholeheartedly agree with Tailwind philosophy.\nAt the time of writing I wasn't aware how to integrate tailwind with maud well,\nso I used `twind` as a client-side Tailwind JIT instead.\n[But I was told that maud + tailwind Just Works](https://github.com/rustshop/htmx-sorta/discussions/11),\nand switched to this approach.\n\n### Points of Interest\n\nCheck [maud templates in fragment.rs](https://github.com/dpc/htmx-sorta/blob/c2d300caafa6a3d72eb7eefcb766b669676ca803/src/fragment.rs),\nacting like web-components for both htmx and tailwind.\n\n[Route handlers are in routes.rs](https://github.com/dpc/htmx-sorta/blob/c2d300caafa6a3d72eb7eefcb766b669676ca803/src/routes.rs).\nThey are a bit low level and manual but hopefully `astra` will get some more convenient approach (e.g. like Axum extractors) in the\nnear future. [The developer is working on it](https://github.com/ibraheemdev/astra/issues/8). Go say hello if you're interested.\n\nThe Nix dev shell I'm using sets up automatically [some cool git hooks](https://github.com/dpc/htmx-sorta/tree/c2d300caafa6a3d72eb7eefcb766b669676ca803/misc/git-hooks). I keep using it in many projects. It includes `semgrep`, `typos` (checking typos), `convco` (conventional commits), linters, and some Rust specific checks.\n\n[`mold` is used to speed up linking, with symbol compression enabled](https://github.com/dpc/htmx-sorta/blob/bc77241ca98e06c7a65e768467d34cbf8bfa8b50/.cargo/config.toml) to make the binary smaller (`6.3 MiB` ATM).\n\nI've \"invented\" [a variable-length sorting key approach, that simplifies\nitem sorting.](https://github.com/dpc/htmx-sorta/blob/c2d300caafa6a3d72eb7eefcb766b669676ca803/src/sortid.rs)\nIt makes generating a key between two other keys a simple and infaliable operation.\n\nI had an idea for [compact and fast, but imprecise pre-rate-limiter](https://github.com/dpc/htmx-sorta/blob/c2d300caafa6a3d72eb7eefcb766b669676ca803/src/rate_limit/pre.rs) that I think would be very fast. It uses a multi-hash approach with buckets of atomic counters, kind of like bloom/cuckoo filters,\nto effective take one atomic (relaxed) write on the happy path, and gracefully degrade under heavy load. Did not have time to benchmark it, so 🤷.\nMaybe it's stupid.\n\nThe rest is somewhat typical. As of the time of writing this there are some known missing things. It's just an demo/research,\ndon't expect too much.\n\n### License\n\nMIT. Feel free to copy, paste and use, no attribution expected.\n","funding_links":[],"categories":["\u003ca name=\"Rust\"\u003e\u003c/a\u003eRust"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frustshop%2Fhtmx-sorta","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frustshop%2Fhtmx-sorta","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frustshop%2Fhtmx-sorta/lists"}