Some great comments in the home page thread shifted toward what you’d like to see in Hologram’s future, particularly standalone mode. I’ve split those comments here so we can have a focused discussion.
Quick context on the two modes:
Embedded (Phoenix-based): The current version where Hologram works as a library within Phoenix applications
Standalone: The upcoming version that will work independently of Phoenix
What would you like to see in standalone mode? What features or capabilities would make it a must-have for your projects?
This is not directly related to the website, but I’d love to see an Igniter installer. I found that it makes it very attractive to try things and maybe just having to mix igniter.install hologram would help adoption
Don’t put a Tailwind in there. Anything JS has the risk of becoming obsolete starting the current time. No JS hate, just JS ecosystem experience.
For me the benefit of Hologram is simply local-first. Some apps benefit from it and not having to fall back to writing API and JS is a major pre. Especially when it can have a ‘no socket (yet)’ mode with loading data from JSON on CDN.
Mostly looking forward to a dramatically simplified scaffold. Phoenix generates a ton of stuff out of the box and I don’t find its overall structure particularly intuitive. Not sure what you had in mind here but maybe it could be super flat
my_app
* api - business logic and schemas live here (or call it core maybe?)
* config
* components
* layouts
* pages
* private
* static
* test
I guess components, layouts, pages could be further nested in ui but I’m not sure it’s worth it.
Yeah, I’m planning something similar! The scaffold will start with horizontal slices (organized by type), with the flexibility to switch to vertical slices (organized by domain and/or feature) later when your app grows - or you can stay with horizontal slices indefinitely if you prefer.
Here’s the initial structure:
app
├── components
├── models # for local auto-sync data store (coming later)
├── pages
├── schemas # if using Ecto
└── services
assets
├── css
├── images
└── static # for assets not requiring fingerprinting (favicon.ico, robots.txt, etc.)
config # required by Mix
priv
└── dist # generated at build (with fingerprinting, etc.)
test
Key decisions:
priv/ and config/ stay at the root - that’s a Mix requirement
assets/static/ is for static assets that don’t need fingerprinting (like favicon.ico, robots.txt, etc.) and gets copied to priv/dist/ at build time
Other assets (CSS, images) get bundled to priv/dist/ with fingerprinting
Two questions for you:
Layouts: Would you prefer app/layouts/ or app/components/layouts/? Layouts are components in essence, but they’re also kind of a separate concept, so I could see it going either way.
Tests: Any thoughts on test/ vs app/test/? Should tests be considered part of the app code itself, or is it better to keep them separate at the root (which is the Mix convention)?
I’d echo the same things I mentioned in the homepage thread (cross-platform development (web/mobile/desktop), vertical slicing architecture (this is extremely appealing to me), and being as intuitive and easy to use as possible)
Another thing I’d add maybe is when it comes to the docs and tutorials, assume people only know the basics (Elixir/html/css) as that will not only make it easy to on-board newbies, but will make it easier for everyone else too - because if something doesn’t quite make sense we could step down a level in the docs or tut and work our way back up from there.
It would be awesome to make it agnostic to the exact frameworks and libraries (well, to the extent possible). In my ideal world (which may be too ideal to be true or not match the project goals) a standalone Hologram would be way more about “transpiling” Elixir to JavaScript rather than a tool for making dynamic web sites.
You know, sort of like transpiling TypeScript to JavaScript or like Babel and webpack transform any JS/CSS/LESS/whatever files into just javascript.
This way I would be able to use awesome Elixir for any JavaScript projects from web sites to Chrome extensions (my current hobby area - so I am obviously biased), to NodeJS-run command line utilities, to even Cordova wrapper-style “mobile” apps which just add native-styled buttons and wrap webview into a Native Chrome.
I realize that such a “purist” approach is probably a bit too much when/if people will just want to make standalone clients for the Phoenix apps. What I hope for is that the solution could be modular enough for the just-a-javascript-transpiler core to be executable in a standalone way.
The vision you’re describing here aligns pretty closely with where Hologram is headed. It’s not meant to be just a web framework - the goal is to build it into a development platform for cross-platform development with isomorphic components that can run through WebView and Web APIs (web/mobile/desktop). Also things like Hologram widgets you can embed in existing apps, JS interop with React/Vue/Svelte, serverless deployments, and eventually web extensions and more targeted transpilation.
The thing is, we need to build this in a specific order. Starting with web makes the most sense because it’s the most urgent community need, and there are already early adopters giving feedback that helps shape the direction. Plus, if we can solve web and local-first well enough, it should create momentum to support the project financially - like through paid courses or content - which would let me work on this full-time.
From there the plan is: PWA → mobile → desktop → extensions/serverless/advanced transpilation features. As I work on the web part, I’m gathering different use cases - for example, when I started I didn’t think about browser extensions at all, but it seems to be one of many possible deployment targets.
One thing I should mention - a lot of people think transpiling to JS is just a 1-1 translation of Elixir code, but it’s actually much more involved. The Elixir world is quite different from the JS world, and concepts don’t translate one to one. You essentially need an Elixir runtime in the browser, call graph analysis, process management eventually, and more. Even if I extracted just the transpilation parts (which would be quite a lot of work since it’s relatively coupled with the framework right now), you’d quickly realize you need much more than just transpilation - you’d basically end up recreating Hologram eventually. I think a much better approach is gradually supporting new use cases through a consistent Hologram development platform and ecosystem.
Anyway, really appreciate you sharing this. It’s good to know the vision resonates with what people are hoping for!
That’s completely aligned with my vision for Hologram!
I want Hologram to be newbie-friendly in the sense that you don’t need to know advanced Elixir concepts to be productive with the framework. The basics of Elixir, HTML, and CSS should be enough to get started. The framework should handle the complex parts for you, letting developers focus on their business logic rather than wrestling with implementation details.
I actually have a simple Elixir video course in my backlog that would walk through just these basic concepts - the essentials you need to be productive.
There’s something I’ve been thinking about regarding how Elixir is typically taught, and this is just what I’ve observed - it’s informed my approach with Hologram. Elixir has multiple differentiators: the functional programming features and the concurrency model/OTP. Both are important, but in practice, the marketing emphasis tends to highlight “fault-tolerant”, “massively concurrent”, “let it crash”, and “OTP” front and center, which makes sense given how unique these capabilities are compared to most other languages. Personally, I find the functional features - particularly immutability and pattern matching - to be the most immediately powerful for day-to-day development.
But I’ve noticed that these advanced concepts tend to be introduced very early in learning materials. I’ve seen anecdotal evidence of people coming from other languages feeling like they need to understand OTP to be “doing Elixir right,” when often they just need the basics to build useful applications. For some newcomers, this can be a bit overwhelming.
I think there might be room for an alternative learning path, especially for web developers: leading with “you can build useful things with just pattern matching, immutability, and basic syntax” might be more welcoming than starting with supervisors and fault tolerance. Then, as you build with Hologram, you’re actually using these powerful features under the hood without needing to understand all the details upfront.
With what’s planned for Hologram, you won’t even need those advanced concepts for most use cases because Hologram will handle them for you - and that’s possible thanks to the reactive/declarative approach. OTP and concurrency can come later, when you’re working on something very specific that needs them.
To be clear, this is just my perspective based on what I’ve observed, and I have tremendous respect for OTP and Elixir’s concurrency features. They’re genuinely revolutionary and absolutely part of what makes Elixir special. I just think offering a gentler learning path for certain audiences - particularly those coming from frontend development or new to backend work - could help broaden Elixir’s accessibility.
I think this is a great strategy Bart. Elixir is an established language now and I think at this stage people care less about the specific details of what makes it so good because it’s already widely regarded that it is - so that will be good enough for most. Hence I feel it is less about the technology now and more about the tools (eg: Phoenix + LiveView) and so approaching things purely from a Hologram-User perspective, where you only cover and introduce concepts that are needed for someone to use Hologram, could work really really well. It will be less overwhelming, easier to get into, and easier to continue progressing - which I think are all important and would be a huge win
No Javascript, right? I tolerate Javascript as a language but hate all the javascript toolchains and eco-system. Please make a goal of not depending any npm packages or javascript build tools.
Getting rid of the Node/npm dependency is actually a core part of the standalone Hologram effort. The plan is to vendor essential JS libraries and eliminate the need for npm/build tools altogether.
This will be part of v0.7.0, and it’ll apply to both the standalone and embedded (Phoenix-based) versions. So you’ll be able to work with just Elixir, HTML, and CSS - no JavaScript toolchain required (unless you need specific npm packages for JS interop).
You know, one very weird realization I’ve had is that the declarative style that React enables and OTP supervisors exhibit are fundamentally the same thing, except that React is considerably more sophisticated. Particularly with how it deals with state, which is something that OTP kind-of just encourages you to throw away a lot of the time.
I am reminded of @zachdaniel 's “let it heal” post from not long ago. Fundamentally I don’t think OTP provides very sophisticated “healing” behavior. If you want to know what “healing” really looks like in a distributed system, have a look at the FoundationDB paper. They take a frankly brilliant declarative approach to recovery which, for the same reason that it helps to avoid bugs in apps built with React, is also excellent for avoiding bugs in otherwise complex distributed systems. There is actually a section near the bottom where they specifically detail a bug which never surfaced because the declarative recovery process completely masked it.
With OTP there is a strong focus on fault tolerance, but less focus on the even greater benefit of declarative programming: it’s actually a very good technique for avoiding bugs entirely because it avoids the complexity explosion that occurs when you write delta code.
Both databases like FDB and app frameworks like React benefit immensely from this approach, but OTP is somewhat left out. It provides no means to resynchronize state across restarts like you see with e.g. React’s hooks or FDB’s recovery. Perhaps to some degree this is just because OTP is very old, and some of these ideas are much newer. But I think its designers must have had some idea of what needed to be done, as exhibited by the hot code reloading functionality that none of us ever use…
All this to say: an experienced frontend dev should actually be very unimpressed with OTP Supervisors, as they have seen things which are far more extraordinary