Everything old is new again. From my perspective as a Rails developer in the past, who landed on Elixir/Phoenix 10 years ago, Elixir and Phoenix were both born from Rails devs who were tired of Rails magic, keeping just the structure and bare minimum.
I've watched Ash spring up and build steam over these past several years with a bit of dread. From my perspective, it's kind of counter to the philosophy I liked in Elixir. I don't want to "derive" things based on a definition, for the most part. Elixir tends to avoid codegen and macros as much as possible, and José has recommended that if there _are_ macros, they should be a very light layer over calling functions, which should be the primary interface.
All this is said without having tried Ash, so I could be way off base. But I've been mostly ignoring it and wondering if I'll have to actually use it someday, and then be back in Rails-y magic land. I also use Scala at work, and saw how a philosophical split in the community just kind of trashed the language (from my perspective). It used to be a cool, better Java, but then those dang Haskell type astronauts found it and made everything impossible to understand.
Just taking the automatic Authentication, for example: Phoenix settled on a `mix` generator for it, to actually put the code and logic into the app itself. This is surely informed from José's years of experience maintaining Devise. If the best those two could come up with is a code generator, then I'm skeptical whatever Ash does here will be better. It feels like it's just heading right back to Devise land. And that was a successful place, and Rails and all its gems are still around, but that's kind of the "old world" philosophy and again doesn't square with us old Elixir developers who were Rails refugees.
I came to Elixir from PHP/Laravel so I approached Ash with a similar skepticism. I was looking specifically for a set of tools that would allow me to rebuild an ancient and unwieldy ColdFusion SAAS product, as a solo dev, with maximum stability and minimum boilerplate. I landed on Elixir+Ash after about a year of exploring other ecosystems and languages.
If you look under the hood of Ash's macros, they're all just shorthand for creating a particular struct with sensible defaults. It's not actually doing a ton of magic. You can replace them entirely with direct function calls, or probably even manually declare the structs yourself.
If there's magic, it tends to be more in the execution step - like how `Ash.read()` can push authorization logic into the query/db layer. But that's exactly the kind of logic I don't want to have to write myself over and over again.
I have never compared Phoenix's generated auth stuff to Ash's so I can't speak to that. However I can say Ash's generators all use `igniter`, which is part of the Ash project. It allows for package developers to reach into Elixir's AST to make smarter installers/updaters, and is being adopted more broadly throughout the Elixir ecosystem. So in terms of code generation Ash's approach is gaining a lot of traction.
Speaking for myself here, I've really liked working with Ash. The value becomes more apparent the more I use it.
> born from Rails devs who were tired of Rails magic
One thing I learned is that we're all different. To me, the magic of Rails is absolutely bonkers, unintuitive, and unmanagable. I also can't work without static types anymore. DHH is apparently my arch nemesis in these regards? Yet I can't definitively say it's because he's inherently flawed.
>> All this is said without having tried Ash, so I could be way off base.
You nailed it. "Magic" is actually a good way to describe it, because much of the developer experience with Ash revolves around figuring out the exact incantation you need to use to make it do what you're trying to do, and the correct intonation and the right amount of reagents.
you can appreciate though how if you are building multiple projects for multiple clients, you'll eventually know all the incantations and it's worth it for your business domain.
Ash, while magic, is mostly a thin layer over calling functions. Often with a lot of ways to go deep down (let's say, by calling ecto functions yourself).
But I do understand you feeling. E.g. I myself have stayed away from things like AshAuth and Ash Forms for now
This is the beauty of Elixir's macros. For a lot of libraries, they are usually just calls to an underlying function with the same name. Because of Elixir's functional style and immutability, it makes it much easier to read through the magic compared to macros in other languages.
That being said, I don't have any hands-on experience with Ash so I can't speak for its approach to macros. I do think Zach's work in the community with Ash/Igniter is something to be applauded for. I'm currently working in a Python codebase that lacks conventions and would kill for something like Ash that provides consistent design patterns.
As many people seem confused, it seems that this framework is a declarative framework (think: expressing a solution like you would in SQL or Prolog), in Elixir, that seems to have the goal of separating out core logic from control flows within web apps, APIs and so on.
Over the course of 15+ years of playing with Rails, I've come to the view of CRUD being a poor choice for most real-world applications and MVC being a useful but often-abused concept. That took me down a bit of a rabbit hole of trying to think about DDD within the constraints of an opinionated framework that thinks CRUD and MVC are the thing that makes you go fast. I, on the other hand, want the thing that makes it easy to extend and maintain. I want actual events to be modeled for all sorts of real-World reasons.
I've been learning Elixir recently because it's something new, the actor model appeals from a concurrency perspective to some of the problems I want to solve, and because Phoenix looks like an interesting and elegant web app framework. However, there was a nag in the back of my head that I'd just end up hitting the same frustrations: I was, and am, ready for that and seeing if anything about Elixir + Phoenix makes life easier than Rails made it.
Ash seems to be a good candidate for part of the puzzle. A declarative framework that brings some packages for useful, often-needed parts of the puzzle (like authentication, authorization, and so on), and it seems to encourage a way of thinking about some key DDD concepts. Resources sound like domains or bounded contexts. Declarative style sounds like it might lend itself to event modeling more easily. Calculated values are a nudge towards "view models".
Never tried, I'm early on my journey, but I think the Ash book will be the first thing I pick up after I've finished the Elixir and Phoenix books I'm reading through. Curious to hear stories from people further down this journey, though!
You sound a lot like me when I first approached Ash a year ago, especially the part about being new to Elixir and worrying I'd just reproduce my prior MVC frustrations (Laravel in my case) in Phoenix.
I've been using Ash for about a year now and it's really hit the spot. Wishing you well on your journey!
I'm planning on trying ash at the weekend when I have time, but right now it's still a little nebulous to me. Have you found a boundary where you end up just being constrained and you're just back to normal phoenix dev?
Not really because Phoenix handles the web layer while Ash handles the domain/application layer. In other words Phoenix provides one interface, of potentially many, through which users could access an application built in Ash.
Which is all to say if there's been something I couldn't figure out in Ash I've tended to put it into a regular Elixir module rather than anything Phoenix-specific.
The only exception I can think of is that AshAuthentication doesn't provide support for API keys out of the box, so I have ended up writing my own little plugs for that.
If you are just getting started I'd strongly recommend working through tutorials and/or the Ash book (it's in beta but pretty solid) rather than just diving into a project. It's a lot when you're first wrapping your head around it.
I've always been a fan of Model Driven Development (MDD), which is by today's standards an ancient paradigm. You define the core data model (resources), properties (attributes), and actions, and auto-generate the UI/API. It was more popular back when OOP first met Web Development. It seems to have fallen to the wayside with manually constructed "fat controllers" being the dominant way to organize web apps today. I have my own framework in MDD style. For a long time I've told people "I can code at the speed of thought." My apps are 80% the data model, 20% the UI, with the middle layer almost entirely generated. Tools like GraphQL, Supabase, and auto-admins kind of go in the same direction.
This is cool, though you would definitely make changes to make UI look decent, and a lot of changes on top of that to make it something that’s a joy to use. For API though, it should probably just work - but then again, there’s tons of stuff like Django REST Framework which, while also a bit dated, works really well in 95% of cases (and lets you handle the other 5%).
Yet here I am, writing CRUD endpoints by hand in Node.js...
Yep I agree, that "20%" UI is mostly custom view-models to give the right UX. MDD is great for development, but users' brains don't exactly fit the model perfectly, particularly for read views. For write functions however, the views just post almost entirely to the generated API.
I've always felt MDD falls short very quickly, because for non-trivial project you often want to show information related to more than one table, and so you have to fallback to writing the controller code manually anyway.
Yep, it can fall down if you force it everywhere. Read views are typically where custom "view models" are needed. For example on my current project with ~30 tables/models (https://humancrm.io), there are only a couple custom user views, and a couple custom write functions to simplify the UI flow. The rest of the API is generated from the data models. I take a pragmatic approach and don't force everything into MDD if there is a clear need.
I am a total noob, ok programmer but not a very good developer.
I'm coming to Phoenix with a Django background and I really enjoy what I've been messing around with so far, but I haven't done anything serious with it.
When I hear people say "ash is like an orm" then that fills me with dread. I actually come to enjoy how elixir/Phoenix/ecto has done things
If I'm trying to build something ie a news aggregator site (like hackernews ) - how would "make it in ash" help me? If it does things for me, does that mean I lose control of those things? Or they are hidden behind some macro magic that I have to pull apart to get to?
Would love any feedback as to whether this helps allay your fear and dread!
Spark is the DSL library that takes a DSL definition as Elixir structs and builds the DSL for you which in turn takes the written DSL and converts to a standard and simple data structure. So there are fewer macros than you might expect. Ash extensions just introspect that generated data structure with ordinary Elixir code.
The main macro in Ash core itself is the `expr` macro which enables portable declarative predicates which can be used in data layers like AshPostgres for filtering in SQL queries. If your data layer is simple like ETS or a CSV then it runs as Elixir code.
Ash will be your Django models. Once you have models (ash resources) built; you can use the Ash ecosystem to get things like a graphql or JSON endpoint (or both!) for those resources with just a few lines of code.
Right and unlike an ORM which only models the "nouns" and "relationships" of your business domain model, Ash also models the verbs.
This allows it to reveal the actions of your system externally via GraphQL or JSON API as well as modelling the data for your relational schema (although data layers are swappable and are not always relational).
FWIW I regret introducing that term into this conversation. I've used it in some cases to try to bring people close to an understanding when we have like...no middle ground. But its nothing close to an ORM.
I'd love to hear from someone who's shipped a product into production with Ash. I've been considering using it for a new project but I'm a bit weary of introducing a whole second language. With it being macro based rather than functions, I can't help but think it might be tricky to break out of for areas where its opinionated approach don't fit so well.
This is one of the earliest projects we did with Ash. It's a really big app and the customer architect was convinced that if we didn't use Ash then they'd ultimately end up building some custom version of what Ash provides.
I've got an app coming out of beta that runs web accessibility scans, which uses Elixir+Ash. Beta testers loved it, it's been very stable and I barely had to touch it over the beta period.
This app has a lot of complex headless browser flows that rely a lot on Ash.StateMachine, and Ash has only gotten better the deeper I've gotten into it. The app gets more simple and stable the more I integrate with Ash.
The declarative "data-oriented programming" paradigm took some getting used to (I come from PHP) but it makes so much sense and makes it easy to plug Ash resources into any other use case. Deriving a JSON api is an easy example.
In another app I'm using Ash.Reactor to model agentic AI workflows (it's just RAG but with extra steps). Reactor was originally intended as a saga orchestrator that models workflows as a DAG. DAG is the perfect abstraction for this use case and it works ridiculously well.
Only half a data point: I played around with it for a private project. It works but the documentation is far from good enough for production. I was even considering getting the book, but it's not out yet. In my humble opinion, normal documentation should be enough to understand a framework, otherwise you can't expect anyone beyond hobbyist and enthusiast to pick it up.
"Break out" is definitively part of the design goals, so I always felt like they put a hatch.
I wouldn't let the fact that the book is in beta dissuade you from getting it. It's mostly feature complete and is a _fantastic_ resource - it really helped get Ash to click for me, and I've found it a joy to work with after getting that initial ah-ha moment.
I know the Ash team is aware of the documentation challenge, and they are working on it. I feel like the book is an answer to that, and hopefully a lot of the greatness of the book is able to make its way back to the docs.
When I was first getting started with Ash I also found the documentation to be frustrating at times. It's less of an issue for me now that I'm more familiar with it. I asked a lot of questions in the discord and found them to be super responsive.
With the caveat that I’m still learning elixir+ash and just building a small private project, I’ve bought the beta book and it really helped get my head around the concepts even though it’s not finished. I’d recommend it, it’s even on sale at pragprog this week.
Ash itself is fantastic so far. I haven’t worked with anything so productive before. Loving it.
I've been using Ash for a few side projects and recently started using it at the day job too. We're mostly using it for new functionality, with the Ash APIs alongside our existing ones, but planning on slowly moving older things over too. It's been working well so far, and it's been easy enough to use the escape hatches for anything weird we're doing.
Getting started was a bit tricky though - definitely recommend the Ash book there. It works a lot better than the documentation as an introduction.
We use it in production and are really happy with it.
For me, one of the biggest value points of Ash lies in removing the boilerplate without locking you in.
The devs of Ash cleverly use Elixir itself and other big names of the Elixir eco system.
By doing that, they have created a framework that helps you moving more quickly as you don't have to write the same code over and over again (i.e. remove boilerplate) while still giving you the flexibility to escape if something out of the box doesn't fit right away (that's because of how Elixir works and how they just re-use the other big names, e.g. Ecto, Absinthe,...).
I've tried to write about all of this here if you are interested in reading more:
I tried it out at the start of a new project last year. After 3 weeks, I finally threw in the towel and started from scratch in plain phoenix. By day 2 or 3 I'd surpassed what I'd managed to somehow get working, mostly by trial and error, in Ash.
I am 100% on board with the vision, but the learning curve is absolutely brutal, and at least at the time the documentation was simply not anywhere close to where it needed to be. Something this different needs a truly giant "cookbook" to show, you know, how to use the damn thing. That was lacking and there was nothing to learn from online besides the most basic toy applications. Also, it was, at least at the time, slow as hell. All those damn macros.
Plus - elixir is already niche. Ash is a niche within a niche. I need to be able to hire people who can get up to speed in days, not weeks or months. There's a chicken and egg problem with something this ambitious - no-one uses it because no-one uses it. I hope it breaks out of this dilemma but professionally I can't bet the company that it does.
As I said I really like the idea. Anyone who has maintained an OpenAPI app will jump for joy with documentation and tests moving automatically and in lockstep with the core domain logic. But for me, at the time, it was too early, too risky and too obscure. I do wish it well though - I love these kind of moonshots and I look forward to trying it again as soon as I can.
It's not really producing a whole separate language that I've found. There is a lot of functionality so the learning curve has been pretty steep to start. The macros are for pretty specific things but once you split out stuff like permissions, changes, etc you just use normal elixir modules. I can't think of any situation where I'd need to go outside of it and couldn't. It is built on top of all my normal elixir stuff and I've had no issue using them as normally. I'd definitely suggest reading the book first though there is a lot of unknown unknowns with it.
First of all, its not "macro based", as that implies dark magic and sacrificed goats. The spark dsl underlying all this is just structs all the way down in a nested manner. Just like you would see if you look under the covers of a Absinthe Blueprint produced by that dsl.
The dsl is declarative and allows to express a lot of stuff with less code, but I would say that saying its "macro based" is a bit misleading, although "technically correct". You could achieve the same by just having functions returning structs.
I have replaced a biiiiig nestjs app that exposed graphql with an ash app exposing graphql, and the boilerplate ratio for resolvers etc is bordering on 1:999. Like literally, across a 90 table large application I have maybe 600 lines of "specifically graphql related code" (5-10 lines of code to expose select actions as mutations and queries per resource). As opposed to the nestjs codebase that was using an annotation driven approach and had a gazillion lines of glue code for resolvers and data loading.
Also the authorization logic through the policies is so extremely composable and easy to do when combined with matching on resources it is fantastic. Each resource "owns" its own authorization, so there is no song and dance about figuring out acl from the entry point and then downwards a tree. You just let the resolver resolve its way down the graphql tree or just feed a long ass loader path into Ash.load and each resource is responsible to implement its own policies and you don't have to worry about accidentally leaking data because you access the data from a new entry path that was not locked down because you added a new resolver.
I kept reimplementing the same boring boiler plate every damn time I started a new project and that pain is almost 100% gone.
It is a harsh learning curve for sure, because the one downside of Ash is that you have to do it the "ash way" for stuff to compose as beautifully as it does. Once you really get into the groove making "expression calculations" (basically projections that reach into other resources or columns to make some kind of computed data, but is done in the database layer since you expose it as an expression) that you can compose and make depend on eachother etc it becomes so incredibly fast to make new functionality.
You think about one and one thing and let the framework take care of how to compose the loading and usage of what you make. A much simpler model than "making it yourself" in ecto which I have been doing for 10 years prior.
We have been using Ash at work for the past nine months. Our experience has been brutal. Learning curve is absurdly steep. Macros everywhere means you have to trawl through documentation to find information about the exact thing you're trying to do, and often cannot. Every time you step out of the well-trodden path you're punished with cryptic errors, for which there's nearly nothing on the web, and AI tools are clueless about. So your only option is to post about it in the Ash discord (which is for some reason not part of the official Elixir discord) and hope that someone responds before you lose your mind.
The only thing it has done for us is that our data layer has started to look somewhat standardized. This may be a reasonable benefit for larger teams that don't have any code quality or architecture discipline. For small teams though, and especially for solo projects, I wouldn't recommend it. Your productivity will suffer.
I've been working on a project for a few months, and I had some of those initial pain points early on as well. I've actually found the codebase surprisingly approachable and have found the team to be very open to bugs and merging PR's. Many times I've created a bug report, and within a day, it's been fixed, or within a day I was able to track down the bug and open a PR to fix it.
Maybe it's just me, but I found the Ash (and ecosystem) codebase a lot more approachable than something like Rails.
The first few weeks on the project were tough, and the documentation challenges are certainly there, but they get better day by day.
After getting comfortable and accepting the "Ash" way, I've found my productivity to skyrocket when using Ash to build an Absinthe GraphQL api. Previously I'd have to build the context layer, then the resolvers, etc.
Now with Ash, I write my action, declare my query/mutation/subscription and get all the rest for free. I can't see myself going back to writing Elixir apps without Ash.
I'm honestly really sad to hear you've had a bad time. My apologies.
Quite a few users have commented that the free support in Discord is incredibly fast and comprehensive. Zach responds unreasonably quickly and often you've run into a bug or unclear documentation that is fixed virtually instantly.
Like Zach mentioned, please help us understand where your challenges are and we'll do our best to help out. We can only improve things for everyone if we know where to focus our attention.
At the risk of being called a shill, if you need more reliable paid support then please reach out, we have a service for this which teams find really valuable. https://ash.alembic.com.au/ash-premium-support
I started using it because I just found it a much nicer way to define my data, auth and interactions with it compared to contexts. It also makes it easier to reuse it and because of the way the data is modeled you get a lot of nice things like the ashphoenix forms which make dealing with them a lot nicer in my opinion.
I'm also likely to be hiring soon so having a well defined way to well..define things seems like it will make it easier with onboarding but I haven't tested this yet.
I'm also very comfortable with Phoenix and Ecto (and LiveView), and initially found Ash a challenge to wrap my head around. After working through the book and really keeping an open-mind on my next project, I've found it a real joy to work with.
Keep in mind that Ash doesn't really replace Phoenix or LiveView (or Ecto), but it's built on top of it. You can still use Phoenix and LiveView the same way you are today, and just rely on Ash to build your context for you and how you interact with your resources. So I'd say it "replaces" Ecto in that sense (though it's all Ecto under the hood).
For me, I'm building a native app with a GraphQL backend and it has been an amazing productivity increase. With Ash, GraphQL on the backend and React and gql.tada (https://gql-tada.0no.co/) on the front-end providing a fully typed experience, I feel even more productive than using LiveView.
As a quick example - I have an existing derived GraphQL endpoint with a query for getting a resource, and I can have basic filters and sorting out of the box from Ash (i.e. filter by status, sort by name, filter by date greater than X, etc.)
Recently, I needed to build a feature to support adding a tag to a resource. I modeled the relationships (join models, etc.), made the necessary additions to my create/update actions and without _any_ changes to my GraphQL setup, I was able to support filtering my resource by tag (or tags) basically for free.
Can I build that in Ecto directly within my Phoenix context? Of course, but I didn't need to - Ash derived that functionality for me, and built that in, with all of the necessary preloading through dataloader and all of that for me, so the queries are optimized.
Ash is a huge mindset shift, and I think it'd be tough to incorporate it into an existing project, but if you're able to start a new project from scratch, I really recommend you give it an honest try. Especially if you think you might need to have additional data channels (i.e. LiveView and GraphQL or Json API).
If you've tried to make a JSON API with Phoenix, it can be pretty cumbersome to generate an OpenAPI spec for the project. It's a very manual and tedious process, even when working with OpenApiSpex (the go-to Elixir library for generating an OpenAPI specs). And if your code implementation changes, then you often have to update your spec to match it.
With Ash, the same data used to model your application is also used to derive the data needed to build the OpenAPI spec. So there's a real value proposition there IMO. It eliminates much of the problems of keeping your spec in line with your code, since they are both modeled in a single location.
Disclaimer: I only learned this by working through the book, so I haven't actually gotten to experience anything off the happy path.
I just wrote a post which attempts to explain the big ideas in Ash as I see it. Would love your feedback on whether this helps answer your excellent questions
There are other methods, e.g. it’s probably available in all major distros’ package managers right now, as well as in Homebrew on macOS and Choco on Windows.
And curl|bash alone is probably okay-ish? You’re still running the code ultimately, so you either trust it or not. It’s what I use for my own project (with a twist: you get the chance to read the script before you run it): https://lunni.dev/docs/install/
But combined with the “ai_personal_chef” it really tripped me off. What the hell is that even supposed to mean? Do I pipe a code written by LLM directly into my shell? (Probably not, it would be pretty expensive for them to run that.)
Ahhhh, okay! Looks like I’ve got a bad roll of a dice then. (The `uber_for` is actually hilarious :-)
Maybe move the script to something like ash-hq.org/new?project_name={generated}, so that it’s easier to guess what’s going on? Or break it up into steps, like:
# Install prerequisites (Elixir and `igniter_new`):
curl -fsSo 'https://ash-hq.org/install?with=phoenix' | sh
# Create a new app:
mix igniter.new {{ generated }} --yes-to-deps --yes --install ""
cd {{ generated }}
# Install Ash:
mix igniter.install ...
(This could also let you eliminate that “Already have an app?” button-link – the users can just skip the steps they’ve already done.)
I guess I'll give it another try. I quite liked the idea behind it but last time I tried, I gave up mid way. Because everything was a macro, there was no auto-complete and that coupled with sparse documentation with buggy website (at the time, looks like its completely different now) was too frustrating.
I also wonder how well this would work with upcoming type system.
The Ash DSLs get full autocomplete from your LSP and so make sure this is setup. The new Elixir LSP called Expert - https://expert-lsp.org/ is coming soon and aims to make this a much smoother process.
The documentation has been overhauled multiple times and is constantly being improved. If you encounter issues please raise an issue or a PR, knowing where users get confused is important for improving the docs for everyone.
One issue that new users often run into is that Ash is spread over multiple packages for different extensions and Hex didn't support multiple package search, which is being currently improved. So double check you're searching in the right package. Dash can help with this offline if you have it.
Tidewave (https://tidewave.ai/) MCP can help with doc search too if you are using a LLM/AI assisted editor like Cursor, Windsurf or Claude Code, etc. We also have some Ash specific announcements this week along these lines... ;)
I wouldn't bother. We have been using Ash at work for the past nine months. I'm not a fan, and dread using parts of the app that are built with Ash. It makes my productivity plummet due to cryptic error messages, really poor documentation, and high levels of obfuscation (by way of countless macros) that hides what is happening under the hood. Based on my conversations with other team members, most of the team feels this way. The only reason we're continuing to use it because it enforces a level of standardization on the codebase.
Would love to have some conversations about specific bad error messages and indirection that causes problems. Please open issues or reach out, I'm happy to help.
I dread returning to it after not having used it for a while, as I forget everything :)
Most cryptic messages I've encountered can usually be understood, as they tend to be in the same format and/or Spark errors. However, when they are cryptic, they are definitely cryptic :) (though I can't produce one off the top of my head right now).
Also, error messaging is improving with new releases.
I ran the install link in the home page and got an empty phoenix project. How am I supposed to understand what to do next? How to add a resource/domain etc. I thought it was a full example. Or at least I'd get a CLI tutorial to create my first resource i.e.
Don't get me wrong. I really support these kind of frameworks. I'm a fan of Rails, Phoenix, Django and Laravel. But if me, as a strong supporter, can't get it right; how can someone who's skeptical?
This is exactly why honest feedback is super valuable. If we don't know where new users get stuck or confused then we can't make it better for the next person.
We'll definitely be looking at how to make it even better, because the Igniter tasks are intended to make things easier and should help explain how to get started effectively and be productive as quickly as possible.
Have you got any thoughts on how we could improve this? Perhaps a suggestion of running the generate domain or resource mix task next once the install is done?
Ash models an application's verbs or operations as actions. This allows the production of events via an "Aspect Oriented" way of hooking into the action lifecycle.
Although it doesn't support a command first Event sourcing approach, AshEvents (https://github.com/ash-project/ash_events) does help produce events that could be replayed.
Torkild wrote an article about his latest updates to AshEvents here:
The GraphQL layer is built on top of Absinthe. If you really find something you can't model with Ash's actions, you can always just jump to your Absinthe schema and write you own queries/mutations/subscriptions. You'll just need to write your own resolver.
I feel as though this website does a poor job of telling me what the framework actually does. There's the mostly-fluffy marketing lead text, followed by an overly-complicated configurator to generate a project.
What can I actually do with this? What problems does it solve? Where is it located relative to other solutions in the same space? What is that space?
I've talked about this a few times and this is the shortest answer to this question. The first part of this talk may help explain concisely where Ash fits at a higher level.
Ash Framework was created to solve a fundamental problem in (web) application development for business apps. When you build a new app, you want to focus on the valuable, innovative parts - what's visible above the waterline of the iceberg. However, modern web applications require an enormous amount of "below the waterline" functionality that's essential but not where you want to spend your time.
Running a consultancy and building various client projects highlights this challenge. Everyone wants to focus on the core, valuable features, but must also deal with relatively boring, commodity problems that have been solved countless times before. This often means reinventing the wheel, which clients understandably see as low-value work.
Authentication is a perfect example - most customers don't even specify login functionality as a feature. Similarly, admin interfaces are considered table stakes for modern applications. The list is extensive: admin UIs, observability, security, and more. All important, but time spent there can feel wasteful when you'd rather be innovating.
Ash's primary goal is to keep you focused on the innovative work above the waterline while minimizing time spent below it. The framework accomplishes this by modelling your domain and deriving everything else.
This is a default pitch for a framework, which is at least as old as Ruby on Rails (an today it sounds more like a pitch for low-code platform than a framework). Is this framework's approach different from RoR/Django in any way, or it is just filling the vacuum in Elixir ecosystem?
I've got to be honest. The comment you're replying to is spot on.
The headline, "Model your domain, derive the rest" is fine by itself. But the paragraph underneath is just dismissible drivel; sure, I could click through the links to more detail, but you've not given me a reason to do so... you've not set the hook. Once I did click through the links, I'm either in the documentation, which is way too much, or at YouTube, etc. The opening paragraph doesn't give me enough reason to click through the links, and if I do I'm given what feels like a firehose.
I appreciate that's pretty harsh assessment of your landing page, but that's exactly how it strikes me and I think you need to hear it if your goal is really to capture audience. That landing page should give me the gist of what you do, several short paragraphs outlining the higher level features... I dunno, call them "selling points"... something that can give me cause to care enough to dig into some details. Once I care, then sure... I'll dive into the docs or watch a video.
As for the book ad other comments talk about: it's fine. I would expect that people that know what Ash Framework is also come to the page and having that out front isn't a problem and speaks to the existing community.
Personally, I already know what Ash Framework is, so I know you have some good selling points that could be summarized and that would be of interest to people. You just need to get them out front in as pithy a way as possible.
That's really helpful feedback and there are few comments mentioning exactly this and you're right, we can definitely explain more up front on the landing page so it's more obvious.
...do you think the book is like a money grab or something? We put it big on the site because a bunch of our users were excited about it and found value from it. The book doesn't even remotely pay for itself.
Coming to the site from an aggregator (and needing to be convinced to use Ash, rather than coming there directly and already knowing I want to use ash) I found the book a little weird to be so front and center.
I would have really hoped for a small code snippet or screenshot showing how powerful the framework was. And a book a little further down from that would be nice. But "pay to learn" before "here's a quick snippet on why ash is neat" would have made me more excited for this thing I hadn't heard of before, and who's website I was visiting to learn about.
---
Seeing a book first gave me a different impression -- like one of the old snooty languages/tools from twenty years ago that was really enterprise-only.
I can tell that's not the vibe Ash is aiming for, but it's what I picked up!
(Somehow, I also couldn't find the documentation link on the first two tries. But that's also my eyes being weird and missing the sticky header where it clearly says Documentation!)
> ...do you think the book is like a money grab or something?
Yes. Regardless of what you intended, IMHO, it comes off as a money grab, and the fact that it glows and "Get the book" is in that high contrast purple doesn't make it better. Maybe it's just me, but I would suggest making it less conspicuous.
edit: and the book image causes a content layout shift when it loads
I appreciate the perspective. Honestly for us it was just something that our whole user base was mega excited about, and so we made a big deal about it. It seemed like a positive that there was a book available (especially given that young-ish frameworks benefit from some level of legitimacy, given that it's a Prag Prog book etc.). I never even considered that it would rub people the wrong way honestly.
I think I'll probably keep it front and center for now, given that the book will be launched out of beta in the near future, but I can see how it might give the wrong idea, and will reconsider its placement going forward
About books: I had a horrible experience in the past with Trailblazer, the Ruby library.
The documentation was horrible, and only had extremely basic examples. The recommendation to any question I saw online was always to buy the book for almost anything. The goal of the bad docs was clearly to encourage people to buy the book. That rubbed me off and it felt like a cash grab.
And of course I'd buy a book and donate for a library I'd want to support, but for Trailblazer's case it's the opposite, I never voluntarily chose to use it and actually would like it to die.
> Running a consultancy and building various client projects highlights this challenge. Everyone wants to focus on the core, valuable features, but must also deal with relatively boring, commodity problems that have been solved countless times before. This often means reinventing the wheel, which clients understandably see as low-value work.
So wordpress or prestashop should be enough for 95% of your needs if you're a consultancy.
Absolutely, if your customers want websites or ecommerce shops, then that's totally true.
The context here is that Alembic builds custom business applications where these problems have not typically been solved before. We want to spend most of our development time on the core business problem not rebuilding things like Content management systems or Ecommerce shopfronts.
This is not a new problem. It is exactly what a web application framework like, e.g. django has been handling for one and a half decades.
What does it do that django doesn't?
A lot of competitors to django have also fallen behind because they either railroad you too much (e.g. by making immutable assumptions about how you want authentication to work which often end up being faulty) or go too far in the other direction and require an excess of boilerplate. This is a very subtle and tricky trade off that most newcomers to the space fail badly at.
But you aren’t required to use Phoenix with an Ash project. Ash will happily work as a standalone CLI, terminal app or some other Elixir web framework that comes out tomorrow.
The forms https://hexdocs.pm/ash_phoenix/AshPhoenix.Form.html seem even more low level than Django forms, and those are notorious for being too low level and annoying to work with. This to me seems to run counter to the tagline. Compare with iommi for Django where you can truly "derive the rest" from the domain model to get forms and tables.
There is definitely room for the Phoenix Form helpers to do more. Iommi looks like a really interesting approach I hadn't seen before.
For example AshAdmin (https://github.com/ash-project/ash_admin) takes these ideas further and generates a full super admin interface for you. It's a bit clunky and you should ultimately write your own admin, but it lets you focus on the important parts first.
For anyone else who hasn't seen it Iommi's motivation and docs are here:
Unlike Django, Ash is not a web framework, it’s an *application* framework.
One way to think of it is that it’s a flexible and extensible domain modelling language that also happens to derive an Elixir application which can be called from Phoenix web UI (or something else like an API, a terminal UI or even an MCP server.
Rails are definitely inspiration for the way Ash DSLs are used to model your business domain, but Ash takes this idea way further.
Ash models nouns and relationships like ActiveRecord does, but it also models Domains (think DDD bounded contexts) and Resources with the verbs or "actions" of your system.
It also lets you configure generated APIs and your data layer (eg Postgres) so it doesn't stop at just how an ORM may typically model your data.
Always cracks me up. In previous life I worked in creative agency and we had a Project Manager called Ruby. Sometimes parties were getting out of hand and she got a nickname Ruby on Rails when she dropped a baggie on the table and made herself two lines (rails) with company credit card.
We've always had trouble with this. The closest thing to Ash I've seen elsewhere is an ORM. It's not an ORM though.
Ash is a declarative application framework. You define your application logic using Ash.Resource, which model things like state, but most importantly actions.
Another analogy is that it's similar to GraphQL, but lowered down to the backend layer. It's a declarative, typed application description and implementation framework, that you can derive a GraphQL from (amongst many other things).
Another way to think of it is a whole ecosystem of packages that standardize the vast majority of things you want to do when building an Elixir backend, instead of trying to kludge together a bunch of different tools. Pagination, sorting, filtering, authentication, authorization, all builtin and designed to work together.
That's certainly more helpful, yeah! My biggest complaint is that that's really not particularly obvious from the home page; I didn't realise the highlighted words in the lead were links, and they're all to a diverse set of locations, which I'm unlikely to check out if I just want a ten-thousand-foot view of the framework.
I'd suggest putting a description similar to your last paragraph on the home page, and including a brief example of what that translates to. Phoenix's website [0] does this beautifully: within the first page of scroll, I immediately know what it does and how it looks, and the following pages of scroll give me the detail I need to evaluate it properly.
Yes, this is a good description. The way I explain it is that "Ash is a declarative, composable application framework."
It is the middle layer between DB (Ecto) and Phoenix (with or without LiveView) -- where your actual application lives.
The difference between a Resource and a Model (or ActiveRecord) is Models typically define attributes and relationships vs a Resource defines attributes, relationships, actions (read, write, destroy, custom...), behaviours (i.e. multi-tenancy, jobs) and what I call facets (i.e. JSON api, GraphQL).
When you read the code for a Resource, you grok all of this in a nice, consistent way (we have 100* resources - all are consistent). This is because of the DSL.
When compiled, it all boils down to a Struct that you can easily inspect. That Struct enables all kinds of stuff.
I hear what you say. I personally blame the flurry of BS js "frameworks" that have more effort put in their Apple-wannabe front page than in actual practical engineering. I think they've setup a weird standard for framework front page that this one seems to follow.
I don't blame the Ash guys, I blame the people who created the trend and those supported who it. I look at you, JS community.
Everything old is new again. From my perspective as a Rails developer in the past, who landed on Elixir/Phoenix 10 years ago, Elixir and Phoenix were both born from Rails devs who were tired of Rails magic, keeping just the structure and bare minimum.
I've watched Ash spring up and build steam over these past several years with a bit of dread. From my perspective, it's kind of counter to the philosophy I liked in Elixir. I don't want to "derive" things based on a definition, for the most part. Elixir tends to avoid codegen and macros as much as possible, and José has recommended that if there _are_ macros, they should be a very light layer over calling functions, which should be the primary interface.
All this is said without having tried Ash, so I could be way off base. But I've been mostly ignoring it and wondering if I'll have to actually use it someday, and then be back in Rails-y magic land. I also use Scala at work, and saw how a philosophical split in the community just kind of trashed the language (from my perspective). It used to be a cool, better Java, but then those dang Haskell type astronauts found it and made everything impossible to understand.
Just taking the automatic Authentication, for example: Phoenix settled on a `mix` generator for it, to actually put the code and logic into the app itself. This is surely informed from José's years of experience maintaining Devise. If the best those two could come up with is a code generator, then I'm skeptical whatever Ash does here will be better. It feels like it's just heading right back to Devise land. And that was a successful place, and Rails and all its gems are still around, but that's kind of the "old world" philosophy and again doesn't square with us old Elixir developers who were Rails refugees.
I came to Elixir from PHP/Laravel so I approached Ash with a similar skepticism. I was looking specifically for a set of tools that would allow me to rebuild an ancient and unwieldy ColdFusion SAAS product, as a solo dev, with maximum stability and minimum boilerplate. I landed on Elixir+Ash after about a year of exploring other ecosystems and languages.
If you look under the hood of Ash's macros, they're all just shorthand for creating a particular struct with sensible defaults. It's not actually doing a ton of magic. You can replace them entirely with direct function calls, or probably even manually declare the structs yourself.
If there's magic, it tends to be more in the execution step - like how `Ash.read()` can push authorization logic into the query/db layer. But that's exactly the kind of logic I don't want to have to write myself over and over again.
I have never compared Phoenix's generated auth stuff to Ash's so I can't speak to that. However I can say Ash's generators all use `igniter`, which is part of the Ash project. It allows for package developers to reach into Elixir's AST to make smarter installers/updaters, and is being adopted more broadly throughout the Elixir ecosystem. So in terms of code generation Ash's approach is gaining a lot of traction.
Speaking for myself here, I've really liked working with Ash. The value becomes more apparent the more I use it.
> born from Rails devs who were tired of Rails magic
One thing I learned is that we're all different. To me, the magic of Rails is absolutely bonkers, unintuitive, and unmanagable. I also can't work without static types anymore. DHH is apparently my arch nemesis in these regards? Yet I can't definitively say it's because he's inherently flawed.
>> All this is said without having tried Ash, so I could be way off base.
You nailed it. "Magic" is actually a good way to describe it, because much of the developer experience with Ash revolves around figuring out the exact incantation you need to use to make it do what you're trying to do, and the correct intonation and the right amount of reagents.
you can appreciate though how if you are building multiple projects for multiple clients, you'll eventually know all the incantations and it's worth it for your business domain.
Ash, while magic, is mostly a thin layer over calling functions. Often with a lot of ways to go deep down (let's say, by calling ecto functions yourself).
But I do understand you feeling. E.g. I myself have stayed away from things like AshAuth and Ash Forms for now
This is the beauty of Elixir's macros. For a lot of libraries, they are usually just calls to an underlying function with the same name. Because of Elixir's functional style and immutability, it makes it much easier to read through the magic compared to macros in other languages.
That being said, I don't have any hands-on experience with Ash so I can't speak for its approach to macros. I do think Zach's work in the community with Ash/Igniter is something to be applauded for. I'm currently working in a Python codebase that lacks conventions and would kill for something like Ash that provides consistent design patterns.
As many people seem confused, it seems that this framework is a declarative framework (think: expressing a solution like you would in SQL or Prolog), in Elixir, that seems to have the goal of separating out core logic from control flows within web apps, APIs and so on.
Over the course of 15+ years of playing with Rails, I've come to the view of CRUD being a poor choice for most real-world applications and MVC being a useful but often-abused concept. That took me down a bit of a rabbit hole of trying to think about DDD within the constraints of an opinionated framework that thinks CRUD and MVC are the thing that makes you go fast. I, on the other hand, want the thing that makes it easy to extend and maintain. I want actual events to be modeled for all sorts of real-World reasons.
I've been learning Elixir recently because it's something new, the actor model appeals from a concurrency perspective to some of the problems I want to solve, and because Phoenix looks like an interesting and elegant web app framework. However, there was a nag in the back of my head that I'd just end up hitting the same frustrations: I was, and am, ready for that and seeing if anything about Elixir + Phoenix makes life easier than Rails made it.
Ash seems to be a good candidate for part of the puzzle. A declarative framework that brings some packages for useful, often-needed parts of the puzzle (like authentication, authorization, and so on), and it seems to encourage a way of thinking about some key DDD concepts. Resources sound like domains or bounded contexts. Declarative style sounds like it might lend itself to event modeling more easily. Calculated values are a nudge towards "view models".
Never tried, I'm early on my journey, but I think the Ash book will be the first thing I pick up after I've finished the Elixir and Phoenix books I'm reading through. Curious to hear stories from people further down this journey, though!
You sound a lot like me when I first approached Ash a year ago, especially the part about being new to Elixir and worrying I'd just reproduce my prior MVC frustrations (Laravel in my case) in Phoenix.
I've been using Ash for about a year now and it's really hit the spot. Wishing you well on your journey!
I'm planning on trying ash at the weekend when I have time, but right now it's still a little nebulous to me. Have you found a boundary where you end up just being constrained and you're just back to normal phoenix dev?
Not really because Phoenix handles the web layer while Ash handles the domain/application layer. In other words Phoenix provides one interface, of potentially many, through which users could access an application built in Ash.
Which is all to say if there's been something I couldn't figure out in Ash I've tended to put it into a regular Elixir module rather than anything Phoenix-specific.
The only exception I can think of is that AshAuthentication doesn't provide support for API keys out of the box, so I have ended up writing my own little plugs for that.
If you are just getting started I'd strongly recommend working through tutorials and/or the Ash book (it's in beta but pretty solid) rather than just diving into a project. It's a lot when you're first wrapping your head around it.
Appreciate these thoughts. Would you mind sharing what Elixir and Phoenix books you're working through?
I've always been a fan of Model Driven Development (MDD), which is by today's standards an ancient paradigm. You define the core data model (resources), properties (attributes), and actions, and auto-generate the UI/API. It was more popular back when OOP first met Web Development. It seems to have fallen to the wayside with manually constructed "fat controllers" being the dominant way to organize web apps today. I have my own framework in MDD style. For a long time I've told people "I can code at the speed of thought." My apps are 80% the data model, 20% the UI, with the middle layer almost entirely generated. Tools like GraphQL, Supabase, and auto-admins kind of go in the same direction.
This is cool, though you would definitely make changes to make UI look decent, and a lot of changes on top of that to make it something that’s a joy to use. For API though, it should probably just work - but then again, there’s tons of stuff like Django REST Framework which, while also a bit dated, works really well in 95% of cases (and lets you handle the other 5%).
Yet here I am, writing CRUD endpoints by hand in Node.js...
Yep I agree, that "20%" UI is mostly custom view-models to give the right UX. MDD is great for development, but users' brains don't exactly fit the model perfectly, particularly for read views. For write functions however, the views just post almost entirely to the generated API.
Related thought: "Companies ship their org chart"
(https://en.wikipedia.org/wiki/Conway%27s_law)
Can you expand on this?
I've always felt MDD falls short very quickly, because for non-trivial project you often want to show information related to more than one table, and so you have to fallback to writing the controller code manually anyway.
Yep, it can fall down if you force it everywhere. Read views are typically where custom "view models" are needed. For example on my current project with ~30 tables/models (https://humancrm.io), there are only a couple custom user views, and a couple custom write functions to simplify the UI flow. The rest of the API is generated from the data models. I take a pragmatic approach and don't force everything into MDD if there is a clear need.
Your models/resources do not need to have a 1:1 mapping to your data store.
I am a total noob, ok programmer but not a very good developer.
I'm coming to Phoenix with a Django background and I really enjoy what I've been messing around with so far, but I haven't done anything serious with it.
When I hear people say "ash is like an orm" then that fills me with dread. I actually come to enjoy how elixir/Phoenix/ecto has done things
If I'm trying to build something ie a news aggregator site (like hackernews ) - how would "make it in ash" help me? If it does things for me, does that mean I lose control of those things? Or they are hidden behind some macro magic that I have to pull apart to get to?
"Magic" in software can be good or bad. I've tried to explain the apparent "dark magic" at the end of this article.
https://alembic.com.au/blog/essence-of-ash-framework
Would love any feedback as to whether this helps allay your fear and dread!
Spark is the DSL library that takes a DSL definition as Elixir structs and builds the DSL for you which in turn takes the written DSL and converts to a standard and simple data structure. So there are fewer macros than you might expect. Ash extensions just introspect that generated data structure with ordinary Elixir code.
The main macro in Ash core itself is the `expr` macro which enables portable declarative predicates which can be used in data layers like AshPostgres for filtering in SQL queries. If your data layer is simple like ETS or a CSV then it runs as Elixir code.
Just wanna chime in and say expr is the bomb
Ash will be your Django models. Once you have models (ash resources) built; you can use the Ash ecosystem to get things like a graphql or JSON endpoint (or both!) for those resources with just a few lines of code.
Right and unlike an ORM which only models the "nouns" and "relationships" of your business domain model, Ash also models the verbs.
This allows it to reveal the actions of your system externally via GraphQL or JSON API as well as modelling the data for your relational schema (although data layers are swappable and are not always relational).
FWIW I regret introducing that term into this conversation. I've used it in some cases to try to bring people close to an understanding when we have like...no middle ground. But its nothing close to an ORM.
FWIW, I have the book and I've found it a really good read so far.
Stylewise, It reminded me of reading the original PragProg Rails book back in the day.
It's mostly finished. I just saw it's 40% off this week with the code 2025PERSPECTIVES at https://pragprog.com/titles/ldash/ash-framework/
Always happy to hear about people liking the book!
I'd love to hear from someone who's shipped a product into production with Ash. I've been considering using it for a new project but I'm a bit weary of introducing a whole second language. With it being macro based rather than functions, I can't help but think it might be tricky to break out of for areas where its opinionated approach don't fit so well.
This is one of the earliest projects we did with Ash. It's a really big app and the customer architect was convinced that if we didn't use Ash then they'd ultimately end up building some custom version of what Ash provides.
https://alembic.com.au/case-studies/from-paper-to-precision-...
Nice, thanks for the writeup! A small heads up, Phoenix is listed twice in the tech stack section.
Good catch! The issue is that we list Phoenix and Phoenix LiveView but LiveView doesn’t have its own logo AFAIk
I've got an app coming out of beta that runs web accessibility scans, which uses Elixir+Ash. Beta testers loved it, it's been very stable and I barely had to touch it over the beta period.
This app has a lot of complex headless browser flows that rely a lot on Ash.StateMachine, and Ash has only gotten better the deeper I've gotten into it. The app gets more simple and stable the more I integrate with Ash.
The declarative "data-oriented programming" paradigm took some getting used to (I come from PHP) but it makes so much sense and makes it easy to plug Ash resources into any other use case. Deriving a JSON api is an easy example.
In another app I'm using Ash.Reactor to model agentic AI workflows (it's just RAG but with extra steps). Reactor was originally intended as a saga orchestrator that models workflows as a DAG. DAG is the perfect abstraction for this use case and it works ridiculously well.
Only half a data point: I played around with it for a private project. It works but the documentation is far from good enough for production. I was even considering getting the book, but it's not out yet. In my humble opinion, normal documentation should be enough to understand a framework, otherwise you can't expect anyone beyond hobbyist and enthusiast to pick it up. "Break out" is definitively part of the design goals, so I always felt like they put a hatch.
I wouldn't let the fact that the book is in beta dissuade you from getting it. It's mostly feature complete and is a _fantastic_ resource - it really helped get Ash to click for me, and I've found it a joy to work with after getting that initial ah-ha moment.
I know the Ash team is aware of the documentation challenge, and they are working on it. I feel like the book is an answer to that, and hopefully a lot of the greatness of the book is able to make its way back to the docs.
When I was first getting started with Ash I also found the documentation to be frustrating at times. It's less of an issue for me now that I'm more familiar with it. I asked a lot of questions in the discord and found them to be super responsive.
Also, the book is out now.
With the caveat that I’m still learning elixir+ash and just building a small private project, I’ve bought the beta book and it really helped get my head around the concepts even though it’s not finished. I’d recommend it, it’s even on sale at pragprog this week.
Ash itself is fantastic so far. I haven’t worked with anything so productive before. Loving it.
I've been using Ash for a few side projects and recently started using it at the day job too. We're mostly using it for new functionality, with the Ash APIs alongside our existing ones, but planning on slowly moving older things over too. It's been working well so far, and it's been easy enough to use the escape hatches for anything weird we're doing.
Getting started was a bit tricky though - definitely recommend the Ash book there. It works a lot better than the documentation as an introduction.
We use it in production and are really happy with it.
For me, one of the biggest value points of Ash lies in removing the boilerplate without locking you in.
The devs of Ash cleverly use Elixir itself and other big names of the Elixir eco system. By doing that, they have created a framework that helps you moving more quickly as you don't have to write the same code over and over again (i.e. remove boilerplate) while still giving you the flexibility to escape if something out of the box doesn't fit right away (that's because of how Elixir works and how they just re-use the other big names, e.g. Ecto, Absinthe,...).
I've tried to write about all of this here if you are interested in reading more:
https://www.lukasender.at/ash-the-hidden-champion-of-low-cod...
In the end, it's hard to only write and read about this. You can only "feel" how things change when you actually work with it.
The learning curve is a little step at first, though (in my opinion). But the docs got a lot better over time.
All in all, I'm still happy with how things turned out and would use it again for future projects.
I tried it out at the start of a new project last year. After 3 weeks, I finally threw in the towel and started from scratch in plain phoenix. By day 2 or 3 I'd surpassed what I'd managed to somehow get working, mostly by trial and error, in Ash.
I am 100% on board with the vision, but the learning curve is absolutely brutal, and at least at the time the documentation was simply not anywhere close to where it needed to be. Something this different needs a truly giant "cookbook" to show, you know, how to use the damn thing. That was lacking and there was nothing to learn from online besides the most basic toy applications. Also, it was, at least at the time, slow as hell. All those damn macros.
Plus - elixir is already niche. Ash is a niche within a niche. I need to be able to hire people who can get up to speed in days, not weeks or months. There's a chicken and egg problem with something this ambitious - no-one uses it because no-one uses it. I hope it breaks out of this dilemma but professionally I can't bet the company that it does.
As I said I really like the idea. Anyone who has maintained an OpenAPI app will jump for joy with documentation and tests moving automatically and in lockstep with the core domain logic. But for me, at the time, it was too early, too risky and too obscure. I do wish it well though - I love these kind of moonshots and I look forward to trying it again as soon as I can.
how did you handle serving more than one version of your OpenAPI endpoint?
It's not really producing a whole separate language that I've found. There is a lot of functionality so the learning curve has been pretty steep to start. The macros are for pretty specific things but once you split out stuff like permissions, changes, etc you just use normal elixir modules. I can't think of any situation where I'd need to go outside of it and couldn't. It is built on top of all my normal elixir stuff and I've had no issue using them as normally. I'd definitely suggest reading the book first though there is a lot of unknown unknowns with it.
Hello, I have two projects in prod on ash!
First of all, its not "macro based", as that implies dark magic and sacrificed goats. The spark dsl underlying all this is just structs all the way down in a nested manner. Just like you would see if you look under the covers of a Absinthe Blueprint produced by that dsl.
The dsl is declarative and allows to express a lot of stuff with less code, but I would say that saying its "macro based" is a bit misleading, although "technically correct". You could achieve the same by just having functions returning structs.
I have replaced a biiiiig nestjs app that exposed graphql with an ash app exposing graphql, and the boilerplate ratio for resolvers etc is bordering on 1:999. Like literally, across a 90 table large application I have maybe 600 lines of "specifically graphql related code" (5-10 lines of code to expose select actions as mutations and queries per resource). As opposed to the nestjs codebase that was using an annotation driven approach and had a gazillion lines of glue code for resolvers and data loading.
Also the authorization logic through the policies is so extremely composable and easy to do when combined with matching on resources it is fantastic. Each resource "owns" its own authorization, so there is no song and dance about figuring out acl from the entry point and then downwards a tree. You just let the resolver resolve its way down the graphql tree or just feed a long ass loader path into Ash.load and each resource is responsible to implement its own policies and you don't have to worry about accidentally leaking data because you access the data from a new entry path that was not locked down because you added a new resolver.
I kept reimplementing the same boring boiler plate every damn time I started a new project and that pain is almost 100% gone.
It is a harsh learning curve for sure, because the one downside of Ash is that you have to do it the "ash way" for stuff to compose as beautifully as it does. Once you really get into the groove making "expression calculations" (basically projections that reach into other resources or columns to make some kind of computed data, but is done in the database layer since you expose it as an expression) that you can compose and make depend on eachother etc it becomes so incredibly fast to make new functionality.
You think about one and one thing and let the framework take care of how to compose the loading and usage of what you make. A much simpler model than "making it yourself" in ecto which I have been doing for 10 years prior.
Echoing my comment from one of the other threads:
We have been using Ash at work for the past nine months. Our experience has been brutal. Learning curve is absurdly steep. Macros everywhere means you have to trawl through documentation to find information about the exact thing you're trying to do, and often cannot. Every time you step out of the well-trodden path you're punished with cryptic errors, for which there's nearly nothing on the web, and AI tools are clueless about. So your only option is to post about it in the Ash discord (which is for some reason not part of the official Elixir discord) and hope that someone responds before you lose your mind.
The only thing it has done for us is that our data layer has started to look somewhat standardized. This may be a reasonable benefit for larger teams that don't have any code quality or architecture discipline. For small teams though, and especially for solo projects, I wouldn't recommend it. Your productivity will suffer.
I've been working on a project for a few months, and I had some of those initial pain points early on as well. I've actually found the codebase surprisingly approachable and have found the team to be very open to bugs and merging PR's. Many times I've created a bug report, and within a day, it's been fixed, or within a day I was able to track down the bug and open a PR to fix it.
Maybe it's just me, but I found the Ash (and ecosystem) codebase a lot more approachable than something like Rails.
The first few weeks on the project were tough, and the documentation challenges are certainly there, but they get better day by day.
After getting comfortable and accepting the "Ash" way, I've found my productivity to skyrocket when using Ash to build an Absinthe GraphQL api. Previously I'd have to build the context layer, then the resolvers, etc.
Now with Ash, I write my action, declare my query/mutation/subscription and get all the rest for free. I can't see myself going back to writing Elixir apps without Ash.
I'm honestly really sad to hear you've had a bad time. My apologies.
Quite a few users have commented that the free support in Discord is incredibly fast and comprehensive. Zach responds unreasonably quickly and often you've run into a bug or unclear documentation that is fixed virtually instantly.
Like Zach mentioned, please help us understand where your challenges are and we'll do our best to help out. We can only improve things for everyone if we know where to focus our attention.
At the risk of being called a shill, if you need more reliable paid support then please reach out, we have a service for this which teams find really valuable. https://ash.alembic.com.au/ash-premium-support
Besides discord, Elixir Forum's Ash section is generally pretty good, too (and is probably better for information retention and searching)
weary (tired) -> wary (cautious / afraid)
I have shipped half a dozen projects based on Phoenix, Ecto and Live View. I love them all, and the language itself the most.
What does Ash Framework offer me? What pain points that I don’t think I have does it solve for me? This I still do not understand.
I started using it because I just found it a much nicer way to define my data, auth and interactions with it compared to contexts. It also makes it easier to reuse it and because of the way the data is modeled you get a lot of nice things like the ashphoenix forms which make dealing with them a lot nicer in my opinion.
I'm also likely to be hiring soon so having a well defined way to well..define things seems like it will make it easier with onboarding but I haven't tested this yet.
(Been using elixir for about a decade)
I'm also very comfortable with Phoenix and Ecto (and LiveView), and initially found Ash a challenge to wrap my head around. After working through the book and really keeping an open-mind on my next project, I've found it a real joy to work with.
Keep in mind that Ash doesn't really replace Phoenix or LiveView (or Ecto), but it's built on top of it. You can still use Phoenix and LiveView the same way you are today, and just rely on Ash to build your context for you and how you interact with your resources. So I'd say it "replaces" Ecto in that sense (though it's all Ecto under the hood).
For me, I'm building a native app with a GraphQL backend and it has been an amazing productivity increase. With Ash, GraphQL on the backend and React and gql.tada (https://gql-tada.0no.co/) on the front-end providing a fully typed experience, I feel even more productive than using LiveView.
As a quick example - I have an existing derived GraphQL endpoint with a query for getting a resource, and I can have basic filters and sorting out of the box from Ash (i.e. filter by status, sort by name, filter by date greater than X, etc.)
Recently, I needed to build a feature to support adding a tag to a resource. I modeled the relationships (join models, etc.), made the necessary additions to my create/update actions and without _any_ changes to my GraphQL setup, I was able to support filtering my resource by tag (or tags) basically for free.
Can I build that in Ecto directly within my Phoenix context? Of course, but I didn't need to - Ash derived that functionality for me, and built that in, with all of the necessary preloading through dataloader and all of that for me, so the queries are optimized.
Ash is a huge mindset shift, and I think it'd be tough to incorporate it into an existing project, but if you're able to start a new project from scratch, I really recommend you give it an honest try. Especially if you think you might need to have additional data channels (i.e. LiveView and GraphQL or Json API).
Add an attribute to a model, run `mix ash.codegen`, it creates migrations for you.
Ash can do paging for you.
You don’t need to create a context file with CRUD functions for your Repo.
See the example repository for the Ash book.
https://github.com/sevenseacat/tunez/tree/end-of-chapter-10
If you've tried to make a JSON API with Phoenix, it can be pretty cumbersome to generate an OpenAPI spec for the project. It's a very manual and tedious process, even when working with OpenApiSpex (the go-to Elixir library for generating an OpenAPI specs). And if your code implementation changes, then you often have to update your spec to match it.
With Ash, the same data used to model your application is also used to derive the data needed to build the OpenAPI spec. So there's a real value proposition there IMO. It eliminates much of the problems of keeping your spec in line with your code, since they are both modeled in a single location.
Disclaimer: I only learned this by working through the book, so I haven't actually gotten to experience anything off the happy path.
There is a post that Mike wrote that describes the thinking behind Ash's declarative approach
https://alembic.com.au/blog/declarative-programming
I just wrote a post which attempts to explain the big ideas in Ash as I see it. Would love your feedback on whether this helps answer your excellent questions
https://alembic.com.au/blog/essence-of-ash-framework
Do these help at all?
https://hexdocs.pm/ash/what-is-ash.html
https://youtu.be/vjnPjrCF4rs?si=sGlfZeEpPrfp1J0K
> sh <(curl 'https://ash-hq.org/install/ai_personal_chef
Thanks no thanks.
Is installing Rust any different?
https://www.rust-lang.org/tools/install
There are other methods, e.g. it’s probably available in all major distros’ package managers right now, as well as in Homebrew on macOS and Choco on Windows.
And curl|bash alone is probably okay-ish? You’re still running the code ultimately, so you either trust it or not. It’s what I use for my own project (with a twist: you get the chance to read the script before you run it): https://lunni.dev/docs/install/
But combined with the “ai_personal_chef” it really tripped me off. What the hell is that even supposed to mean? Do I pipe a code written by LLM directly into my shell? (Probably not, it would be pretty expensive for them to run that.)
Understand the hesitation, but this is just a convenience script to make installation a shell one-liner and totally optional.
Just click on the hard to spot "Already have an app?" link and it will show you the individual mix tasks you can run yourself.
I would argue that this is the preferred way to see what's happening and avoid running a remote shell script for the security conscious. ;)
Also the generated project name is completely random and intended to be humourous.
Ahhhh, okay! Looks like I’ve got a bad roll of a dice then. (The `uber_for` is actually hilarious :-)
Maybe move the script to something like ash-hq.org/new?project_name={generated}, so that it’s easier to guess what’s going on? Or break it up into steps, like:
(This could also let you eliminate that “Already have an app?” button-link – the users can just skip the steps they’ve already done.)I guess I'll give it another try. I quite liked the idea behind it but last time I tried, I gave up mid way. Because everything was a macro, there was no auto-complete and that coupled with sparse documentation with buggy website (at the time, looks like its completely different now) was too frustrating.
I also wonder how well this would work with upcoming type system.
It's definitely worth taking another look.
The Ash DSLs get full autocomplete from your LSP and so make sure this is setup. The new Elixir LSP called Expert - https://expert-lsp.org/ is coming soon and aims to make this a much smoother process.
The documentation has been overhauled multiple times and is constantly being improved. If you encounter issues please raise an issue or a PR, knowing where users get confused is important for improving the docs for everyone.
One issue that new users often run into is that Ash is spread over multiple packages for different extensions and Hex didn't support multiple package search, which is being currently improved. So double check you're searching in the right package. Dash can help with this offline if you have it.
Tidewave (https://tidewave.ai/) MCP can help with doc search too if you are using a LLM/AI assisted editor like Cursor, Windsurf or Claude Code, etc. We also have some Ash specific announcements this week along these lines... ;)
>> I guess I'll give it another try.
I wouldn't bother. We have been using Ash at work for the past nine months. I'm not a fan, and dread using parts of the app that are built with Ash. It makes my productivity plummet due to cryptic error messages, really poor documentation, and high levels of obfuscation (by way of countless macros) that hides what is happening under the hood. Based on my conversations with other team members, most of the team feels this way. The only reason we're continuing to use it because it enforces a level of standardization on the codebase.
Would love to have some conversations about specific bad error messages and indirection that causes problems. Please open issues or reach out, I'm happy to help.
I dread returning to it after not having used it for a while, as I forget everything :)
Most cryptic messages I've encountered can usually be understood, as they tend to be in the same format and/or Spark errors. However, when they are cryptic, they are definitely cryptic :) (though I can't produce one off the top of my head right now).
Also, error messaging is improving with new releases.
I ran the install link in the home page and got an empty phoenix project. How am I supposed to understand what to do next? How to add a resource/domain etc. I thought it was a full example. Or at least I'd get a CLI tutorial to create my first resource i.e.
Check out the docs for the Ash Igniter mix tasks, they will generate skeleton code for you:
https://hexdocs.pm/ash/Mix.Tasks.Ash.Gen.Resource.html will generate a new resource for example (and the Domain if it doesn't already exist).
Check the side bar for other generator mix tasks.
Thanks for the feedback, we'll try and make this DX clearer!
Don't get me wrong. I really support these kind of frameworks. I'm a fan of Rails, Phoenix, Django and Laravel. But if me, as a strong supporter, can't get it right; how can someone who's skeptical?
This is exactly why honest feedback is super valuable. If we don't know where new users get stuck or confused then we can't make it better for the next person.
We'll definitely be looking at how to make it even better, because the Igniter tasks are intended to make things easier and should help explain how to get started effectively and be productive as quickly as possible.
Have you got any thoughts on how we could improve this? Perhaps a suggestion of running the generate domain or resource mix task next once the install is done?
1. Does Ash supports CQRS/ES architecture?
Or alternatively can it be combined with a framework like Commanded?
2. How customizable is GraphQL layer? Specifically error handling/idempotency for mutations?
Ash models an application's verbs or operations as actions. This allows the production of events via an "Aspect Oriented" way of hooking into the action lifecycle.
Although it doesn't support a command first Event sourcing approach, AshEvents (https://github.com/ash-project/ash_events) does help produce events that could be replayed.
Torkild wrote an article about his latest updates to AshEvents here:
https://alembic.com.au/blog/ash-events-event-sourcing-made-s...
The GraphQL layer is built on top of Absinthe. If you really find something you can't model with Ash's actions, you can always just jump to your Absinthe schema and write you own queries/mutations/subscriptions. You'll just need to write your own resolver.
AshGraphQL (https://github.com/ash-project/ash_graphql) errors are relatively customisable
https://hexdocs.pm/ash_graphql/handle-errors.html
I feel as though this website does a poor job of telling me what the framework actually does. There's the mostly-fluffy marketing lead text, followed by an overly-complicated configurator to generate a project.
What can I actually do with this? What problems does it solve? Where is it located relative to other solutions in the same space? What is that space?
I've talked about this a few times and this is the shortest answer to this question. The first part of this talk may help explain concisely where Ash fits at a higher level.
https://youtu.be/10VBTcN8gAo?feature=shared&t=133
Ash Framework was created to solve a fundamental problem in (web) application development for business apps. When you build a new app, you want to focus on the valuable, innovative parts - what's visible above the waterline of the iceberg. However, modern web applications require an enormous amount of "below the waterline" functionality that's essential but not where you want to spend your time.
Running a consultancy and building various client projects highlights this challenge. Everyone wants to focus on the core, valuable features, but must also deal with relatively boring, commodity problems that have been solved countless times before. This often means reinventing the wheel, which clients understandably see as low-value work.
Authentication is a perfect example - most customers don't even specify login functionality as a feature. Similarly, admin interfaces are considered table stakes for modern applications. The list is extensive: admin UIs, observability, security, and more. All important, but time spent there can feel wasteful when you'd rather be innovating.
Ash's primary goal is to keep you focused on the innovative work above the waterline while minimizing time spent below it. The framework accomplishes this by modelling your domain and deriving everything else.
This is a default pitch for a framework, which is at least as old as Ruby on Rails (an today it sounds more like a pitch for low-code platform than a framework). Is this framework's approach different from RoR/Django in any way, or it is just filling the vacuum in Elixir ecosystem?
I've got to be honest. The comment you're replying to is spot on.
The headline, "Model your domain, derive the rest" is fine by itself. But the paragraph underneath is just dismissible drivel; sure, I could click through the links to more detail, but you've not given me a reason to do so... you've not set the hook. Once I did click through the links, I'm either in the documentation, which is way too much, or at YouTube, etc. The opening paragraph doesn't give me enough reason to click through the links, and if I do I'm given what feels like a firehose.
I appreciate that's pretty harsh assessment of your landing page, but that's exactly how it strikes me and I think you need to hear it if your goal is really to capture audience. That landing page should give me the gist of what you do, several short paragraphs outlining the higher level features... I dunno, call them "selling points"... something that can give me cause to care enough to dig into some details. Once I care, then sure... I'll dive into the docs or watch a video.
As for the book ad other comments talk about: it's fine. I would expect that people that know what Ash Framework is also come to the page and having that out front isn't a problem and speaks to the existing community.
Personally, I already know what Ash Framework is, so I know you have some good selling points that could be summarized and that would be of interest to people. You just need to get them out front in as pithy a way as possible.
That's really helpful feedback and there are few comments mentioning exactly this and you're right, we can definitely explain more up front on the landing page so it's more obvious.
Thanks!
When I opened your website first thing I saw was "Get the book" and it's a big red flag for me. No, I don't think I will.
...do you think the book is like a money grab or something? We put it big on the site because a bunch of our users were excited about it and found value from it. The book doesn't even remotely pay for itself.
Coming to the site from an aggregator (and needing to be convinced to use Ash, rather than coming there directly and already knowing I want to use ash) I found the book a little weird to be so front and center.
I would have really hoped for a small code snippet or screenshot showing how powerful the framework was. And a book a little further down from that would be nice. But "pay to learn" before "here's a quick snippet on why ash is neat" would have made me more excited for this thing I hadn't heard of before, and who's website I was visiting to learn about.
---
Seeing a book first gave me a different impression -- like one of the old snooty languages/tools from twenty years ago that was really enterprise-only.
I can tell that's not the vibe Ash is aiming for, but it's what I picked up!
(Somehow, I also couldn't find the documentation link on the first two tries. But that's also my eyes being weird and missing the sticky header where it clearly says Documentation!)
Example: https://vertx.io/
> ...do you think the book is like a money grab or something?
Yes. Regardless of what you intended, IMHO, it comes off as a money grab, and the fact that it glows and "Get the book" is in that high contrast purple doesn't make it better. Maybe it's just me, but I would suggest making it less conspicuous.
edit: and the book image causes a content layout shift when it loads
I appreciate the perspective. Honestly for us it was just something that our whole user base was mega excited about, and so we made a big deal about it. It seemed like a positive that there was a book available (especially given that young-ish frameworks benefit from some level of legitimacy, given that it's a Prag Prog book etc.). I never even considered that it would rub people the wrong way honestly.
I think I'll probably keep it front and center for now, given that the book will be launched out of beta in the near future, but I can see how it might give the wrong idea, and will reconsider its placement going forward
Same.
About books: I had a horrible experience in the past with Trailblazer, the Ruby library.
The documentation was horrible, and only had extremely basic examples. The recommendation to any question I saw online was always to buy the book for almost anything. The goal of the bad docs was clearly to encourage people to buy the book. That rubbed me off and it felt like a cash grab.
And of course I'd buy a book and donate for a library I'd want to support, but for Trailblazer's case it's the opposite, I never voluntarily chose to use it and actually would like it to die.
> Running a consultancy and building various client projects highlights this challenge. Everyone wants to focus on the core, valuable features, but must also deal with relatively boring, commodity problems that have been solved countless times before. This often means reinventing the wheel, which clients understandably see as low-value work.
So wordpress or prestashop should be enough for 95% of your needs if you're a consultancy.
Absolutely, if your customers want websites or ecommerce shops, then that's totally true.
The context here is that Alembic builds custom business applications where these problems have not typically been solved before. We want to spend most of our development time on the core business problem not rebuilding things like Content management systems or Ecommerce shopfronts.
This is not a new problem. It is exactly what a web application framework like, e.g. django has been handling for one and a half decades.
What does it do that django doesn't?
A lot of competitors to django have also fallen behind because they either railroad you too much (e.g. by making immutable assumptions about how you want authentication to work which often end up being faulty) or go too far in the other direction and require an excess of boilerplate. This is a very subtle and tricky trade off that most newcomers to the space fail badly at.
I’d consider Phoenix to be like Flask. Ash fills the gap that brings Phoenix up to feature parity with a batteries included framework like Django.
Ash Admin (Django admin), Ash Resource & Domain (Django models & ORM), Ash JSON (Django Rest Framework), Ash Auth (Django Allauth), Ash Phoenix (Django Forms), Ash policies (Django permissions)
But you aren’t required to use Phoenix with an Ash project. Ash will happily work as a standalone CLI, terminal app or some other Elixir web framework that comes out tomorrow.
The forms https://hexdocs.pm/ash_phoenix/AshPhoenix.Form.html seem even more low level than Django forms, and those are notorious for being too low level and annoying to work with. This to me seems to run counter to the tagline. Compare with iommi for Django where you can truly "derive the rest" from the domain model to get forms and tables.
There is definitely room for the Phoenix Form helpers to do more. Iommi looks like a really interesting approach I hadn't seen before.
For example AshAdmin (https://github.com/ash-project/ash_admin) takes these ideas further and generates a full super admin interface for you. It's a bit clunky and you should ultimately write your own admin, but it lets you focus on the important parts first.
For anyone else who hasn't seen it Iommi's motivation and docs are here:
Motivation https://kodare.net/2024/09/11/why-we-wrote-a-new-form-librar...
Iommi Forms https://docs.iommi.rocks/forms.html
Iommi Github repo https://github.com/iommirocks/iommi
This type of thing is the real measure of a framework.
Thank you for digging.
Thanks. This is exactly what the website should say!
Exactly! That's a great way to think about it in Django terms.
Hi Josh!
Scott from the Gig City conference ;)
Oh hey Scott! :)
They really should put something to that effect on the homepage.
Unlike Django, Ash is not a web framework, it’s an *application* framework.
One way to think of it is that it’s a flexible and extensible domain modelling language that also happens to derive an Elixir application which can be called from Phoenix web UI (or something else like an API, a terminal UI or even an MCP server.
so ruby on rail??
Rails are definitely inspiration for the way Ash DSLs are used to model your business domain, but Ash takes this idea way further.
Ash models nouns and relationships like ActiveRecord does, but it also models Domains (think DDD bounded contexts) and Resources with the verbs or "actions" of your system.
It also lets you configure generated APIs and your data layer (eg Postgres) so it doesn't stop at just how an ORM may typically model your data.
Always cracks me up. In previous life I worked in creative agency and we had a Project Manager called Ruby. Sometimes parties were getting out of hand and she got a nickname Ruby on Rails when she dropped a baggie on the table and made herself two lines (rails) with company credit card.
So Ruby off Rails??
We've always had trouble with this. The closest thing to Ash I've seen elsewhere is an ORM. It's not an ORM though.
Ash is a declarative application framework. You define your application logic using Ash.Resource, which model things like state, but most importantly actions.
Another analogy is that it's similar to GraphQL, but lowered down to the backend layer. It's a declarative, typed application description and implementation framework, that you can derive a GraphQL from (amongst many other things).
Another way to think of it is a whole ecosystem of packages that standardize the vast majority of things you want to do when building an Elixir backend, instead of trying to kludge together a bunch of different tools. Pagination, sorting, filtering, authentication, authorization, all builtin and designed to work together.
That's certainly more helpful, yeah! My biggest complaint is that that's really not particularly obvious from the home page; I didn't realise the highlighted words in the lead were links, and they're all to a diverse set of locations, which I'm unlikely to check out if I just want a ten-thousand-foot view of the framework.
I'd suggest putting a description similar to your last paragraph on the home page, and including a brief example of what that translates to. Phoenix's website [0] does this beautifully: within the first page of scroll, I immediately know what it does and how it looks, and the following pages of scroll give me the detail I need to evaluate it properly.
[0]: https://www.phoenixframework.org/
I will go in and add another section that expands a bit more on what Ash is after ElixirConf EU is over. Thanks for the feedback!
Yes, this is a good description. The way I explain it is that "Ash is a declarative, composable application framework."
It is the middle layer between DB (Ecto) and Phoenix (with or without LiveView) -- where your actual application lives.
The difference between a Resource and a Model (or ActiveRecord) is Models typically define attributes and relationships vs a Resource defines attributes, relationships, actions (read, write, destroy, custom...), behaviours (i.e. multi-tenancy, jobs) and what I call facets (i.e. JSON api, GraphQL).
When you read the code for a Resource, you grok all of this in a nice, consistent way (we have 100* resources - all are consistent). This is because of the DSL.
When compiled, it all boils down to a Struct that you can easily inspect. That Struct enables all kinds of stuff.
This repository from the Ash book gives you an example of what it can do.
Model.
https://github.com/sevenseacat/tunez/tree/end-of-chapter-10/...
View.
https://github.com/sevenseacat/tunez/tree/end-of-chapter-10/...
I hear what you say. I personally blame the flurry of BS js "frameworks" that have more effort put in their Apple-wannabe front page than in actual practical engineering. I think they've setup a weird standard for framework front page that this one seems to follow. I don't blame the Ash guys, I blame the people who created the trend and those supported who it. I look at you, JS community.
(Yeah... this is 100% a rant, sorry)
[dead]