{"id":18993433,"url":"https://github.com/hyperfiddle/electric-datomic-browser","last_synced_at":"2025-04-16T18:31:47.234Z","repository":{"id":90853241,"uuid":"603876929","full_name":"hyperfiddle/electric-datomic-browser","owner":"hyperfiddle","description":null,"archived":false,"fork":false,"pushed_at":"2024-10-21T10:50:07.000Z","size":312,"stargazers_count":16,"open_issues_count":1,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-10-21T15:42:51.177Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Clojure","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/hyperfiddle.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-02-19T20:25:24.000Z","updated_at":"2024-10-21T10:50:11.000Z","dependencies_parsed_at":null,"dependency_job_id":"96ebfd57-4cb6-4e64-bf4d-28e4188b53b4","html_url":"https://github.com/hyperfiddle/electric-datomic-browser","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/hyperfiddle%2Felectric-datomic-browser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperfiddle%2Felectric-datomic-browser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperfiddle%2Felectric-datomic-browser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperfiddle%2Felectric-datomic-browser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hyperfiddle","download_url":"https://codeload.github.com/hyperfiddle/electric-datomic-browser/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223723372,"owners_count":17192120,"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":[],"created_at":"2024-11-08T17:21:21.852Z","updated_at":"2025-04-16T18:31:47.225Z","avatar_url":"https://github.com/hyperfiddle.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Datomic Browser — now Electric v3!\n\nLive app: https://electric.hyperfiddle.net/datomic-browser.datomic-browser!DatomicBrowser/\n\n\u003e [!NOTE]\n\u003e Below is the old readme for the v2 implementation (available in [v2 branch](https://github.com/hyperfiddle/electric-datomic-browser/tree/v2)). As of today (2024 Dec 18) we have a new, better/faster/simpler implementation using Electric v3, however the src is currently in our internal monorepo with our other demos, and we don't yet have a good way to publish the src without needing to maintain yet another standalone repo.\n\u003e \n\u003e Please DM @dustingetz in Slack if you have a use case for this!\n\n# Motivation\n\nToday, Cognitect's REBL and other GUI data browsers are architected as desktop applications, because their expressive power comes from the **datafy/nav programming model**, where the GUI view process is co-located with the backend data sources, so that the view can directly query and traverse backend data structures as if at the REPL (data-navigate = fn composition). \n\nThe consequence of this co-located architecture is that these data browsers are historically not architected as web applications, because the **frontend/backend web app plumbing breaks composition**, which in turn breaks the data-nav=composition programming model. And that means we can't run these in prod, we they aren't linkable/sharable, and worst of all, we can't use the flexible and dynamic programming model based on data-nav=composition to power mission-critical web applications that match how people think.\n\nElectric Clojure solves this at the technical layer by using **stream functions** to abstract over the frontend/backend web boundary, permitting a data-nav=composition programming model to work with high performance despite the client/server architecture.\n\nhttps://user-images.githubusercontent.com/124158/219978031-939344eb-4489-4b97-af9f-4b2df38c70db.mp4\n\n*Video: this web-based data browser achieves high performance while still being coded in the data-nav=composition programming model.*\n\nWhat's happening:\n\n* full-stack web application\n* Datomic Cloud database is on the backend\n* Dynamic web frontend with filtering, query parameters, routing, web history, tree views\n* Pagination is server-streamed and renders as an efficient virtual scroll.\n\nThe key idea here is not what the demo does, but how it is expressed in code:\n\n* Demo is a single file namespace, 228 LOC: [datomic_browser.cljc](https://github.com/hyperfiddle/electric-datomic-browser/blob/main/src/app/datomic_browser.cljc)\n* the application is an expression, the entrypoint [user.cljs](https://github.com/hyperfiddle/electric-datomic-browser/blob/7617d72a34a68223459e2691299bd46283cd334d/src/user.cljs#L9) calls a single Electric function, that's it!\n* The grid cell renderers, despite rendering on the frontend, have full backend access as if co-located. \n\nConcretely, on the Entity Detail page, the valueType and cardianlity column renderers can query the entity schema metadata directly, and intelligently resolve `:db/ident` when available, so that a dynamic renderer can display the most human-friendly identity representation available:\n\n![](docs/20230409-datomic-browser-format-entity-dynamic.png)\n\n*Screenshot: the dynamic entity detail view from this Datomic browser.*\n\nIn this screenshot,\n* the frontend key renderer queries backend schema to check if it matches a schema attr, hyperlinks to schema detail if so [L73-L74](https://github.com/hyperfiddle/electric-datomic-browser/blob/7617d72a34a68223459e2691299bd46283cd334d/src/app/datomic_browser.cljc#L73-L74)\n* the frontend key renderer queries backend schema to check for human readable attr names [L13-L20](https://github.com/hyperfiddle/electric/blob/a1907db5b77931f777205b0fb6b15722154435d8/src/contrib/datomic_contrib.clj#L13-L20)\n* Because it's dynamic, this view works on any tree data structure, not just Datomic entities. That's why the `k` column renderer can expand into collections as a tree, with an \n\nAll of this is done inline in the cell renderer, **without any non-local coordination** to prefetch, batch, cache or mirror entities on the frontend in a client-side db for fast lookups. All that crap is gone—**all app logic is local!**—which means it is easy to reason about. With Electric, as programmers, we no longer need to think about or even care which site their data source exists at. Simply use what you need, and Electric will take care of the plumbing. De-load your mind and relax!\n\nIn essence, Electric's property of **\"network-transparent composition\"** is designed to make possible a datafy/nav implementation that spans the client/server network chasm, all in a way designed to compose seamlessly with dynamic web frontend libraries. Therefore, we think bringing this browser demo to parity with, say, Cognitect REBL (but for the web) is a straightforward exercise. And not just that—we can now use data-nav=composition abstractions as a foundation for full-on applications.\n\nThis is the technical thesis of the Hyperfiddle project. Now armed with network-transparent composition, how much further can our programming abstractions scale, before reaching performance limits that leak incidental platform implementation details/plumbing, that have nothing to do with the business problem at hand? What % of the LOC that we write today, is spent dealing with leaky abstractions?\n\n# Dependencies\n\n* Datomic Pro (now free!)\n* [Electric Clojure](https://github.com/hyperfiddle/electric)\n* hyperfiddle.history (bundled with Electric) – experimental composable router\n* datomic/missionary adapter (bundled with Electric) – experimental streaming adapter for Datomic\n\n# Getting Started\n\n```\n$ git submodule update --init --recursive\n$ ./datomic_fixtures.sh    # create datomic db, download and seed with mbrains sample data\n$ state/datomic-pro/bin/transactor config/samples/dev-transactor-template.properties \u003e\u003estate/datomic.log 2\u003e\u00261 \u0026\n$ clj -A:dev -X user/main\n\nStarting Electric compiler and server...\nshadow-cljs - server version: 2.22.10 running at http://localhost:9630\nshadow-cljs - nREPL server started on port 9001\n[:dev] Configuring build.\n[:dev] Compiling ...\nDatomic APIs detected:  #{datomic.client.api.async datomic.client.api}\n[:dev] Build completed. (225 files, 1 compiled, 0 warnings, 4.69s)\n\n👉 App server available at http://0.0.0.0:8080\n```\n\n# Deployment\n\n```\nfly status\nfly platform vm-sizes\nfly scale show\nfly scale vm shared-cpu-8x # for 2gb ram\nfly scale memory 4096 -a electric-datomic-viewer\nfly regions list\nfly regions add ewr gru sjc cdg\nfly scale count 1 --region ewr\nfly scale count 1 --region cdg\nfly scale count 1 --region sjc\nfly scale count 1 --region gru\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperfiddle%2Felectric-datomic-browser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhyperfiddle%2Felectric-datomic-browser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperfiddle%2Felectric-datomic-browser/lists"}