caslu
My thoughts on Ash
I want to open this thread for you all to discuss and help those who really like Ash but are still hesitant to use it in a real project. I chose Ash for my SaaS that I’m currently developing, but then I decided to abandon it. So here, I’m going to share with you why I made that decision and a little about my opinions about the Ash framework and the Ash ecosystem in general. This post will be a little long, so I ask you to be patient
.
First of all, I want to make some things clear: this is NOT a hate or random critique about Ash! @zachdaniel and all the people who keep maintaining the ecosystem around the framework (Ignite, Ash, AshPostgres, and so on) are like magicians to me. This is really huge, and I’ve never seen anything like it in other languages. Also, the support from Zach is almost instantaneous, so congratulations, guys.
Another important note is that I’m not an Ash expert like the guys who maintain it, but I think the most important point of view for people who maintain the framework is normal user feedback, so I guess my opinions are valid in this sense.
Now, focusing on the title, there’s no better slogan than “model your domain, derive the rest” for describing what Ash is. It’s really what you’ve ever dreamed of: all your web application needs solved in one place. You don’t need to decide about which library to use, check if it’s active or secure; you just plug and play with Ash. I thought it was too good to be true when using it for the first time. You get an amazing and fully featured authorization system (which is something that Phoenix doesn’t give you out of the box), you’ve got authentication, email, soft delete, an admin panel—sometimes it feels like Ash is a perfect SaaS template. And all of this comes with a pretty declarative and beautiful API. But if Ash is so good, why did I quit it?
Well, this is the part where I share some caveats about Ash. Again, this isn’t hate or empty criticism; it’s just my opinion, and I’m assuming that some of these things may just be a “skill issue.” So let’s dive a little into the problems I’ve had with Ash.
Testing
Ash gives me the feeling that it’s useless to test my resources and code in general, and I’ve noticed it’s not very clear how my test designs should look. There’s a lot of discussion around here and in the Discord community, and the documentation only goes so far. In fact, the documentation has very simple examples and resources about testing, and it gets worse when it comes to the main extensions such as AshAuthentication.
Example scenario: Let’s suppose that I’ve set up my User resource with magic link only authentication. What’s the proper way of testing this? Should I even test it? I won’t be testing the framework, will I? What about the policy which checks AshAuthenticationInteraction? Is it good practice to disable it for almost every test?
Also, coverage is a useless metric to define code safety/quality with Ash, since things only run at compile time, so your resources will always remain with 0% coverage.
Learning Curve
I won’t focus a lot on this topic because it depends a lot. I found it easy to do things with Ash, but I spent too much time in the documentation or reading source code, mainly from AshAuthentication. It reminded me of when I first encountered the devise gem in the Rails world, and it also reminded me of José Valim talking somewhere (I think it was during the development of phx.gen.auth) that Devise was a mistake because things just got too magical. I felt this a bit with AshAuthentication. I think there’s a lot of work that could be done in the documentation to solve this, but the code is really understandable. About Ash, I think it’s just a matter of time until you get the hang of things, but it’s kind of boring to open the documentation every time you want to do a preparation, change, or calculation. Again, it could be a skill issue on my part.
Keeps you away from Elixir
I’ve seen too many comparisons between Ash and Ecto, but unlike Ecto, Ash is not a library; Ash is your application. Your entire app will literally derive from it. You cannot decouple Ash, and it would be a silly thing to do. So you basically need to agree to do things the “Ash way.” You eventually get used to it, but I confess that it bothers me a bit, and I still don’t know if Ash is really for every kind of project—not for technical reasons, but for the necessity of wrapping your business around something. I feel like if Zach wakes up and is no longer in the mood to maintain Ash or to answer my doubts, my application would be doomed. ![]()
With a heavy heart, I’ve decided to follow my reason and remove Ash from my project, but I’m still not 100% sure if the good parts don’t compensate for the bad ones. Maybe this thread will give me another perspective. I would be grateful to have a healthy discussion here with those who are using Ash in production, those who maintain the framework, and those who like it a lot, like me, but are still hesitant to use it.
Thanks again to @zachdaniel and all the community for the great work (including myself, as long as my 2 contributions to Ash count
), and please keep doing the great work on it. This is probably the longest post on the Elixir Forum, so sorry about that, guys, but it was for a good cause ![]()
![]()
Most Liked
sodapopcan
To expand on some sentiments above regarding the learning curve and having to reference docs, here is a bunch of text that is a bit ranty:
Aside from Ash’s tag line, Zach often mentions that any significantly large project is going to end up inventing some version—though far more likely versionS—of a part of Ash. In the 15 short years I’ve been writing code professionally this couldn’t resonate more, so much so that I would go as far to say that I think it’s irresponsible not to use Ash on any serious project that’s going to one day have people coming off of and onto it. This may sound a little hyperbolic, and it is, but I stand by it (just my opinion, of course).
The key thing here is that if you don’t use Ash, you are going to be faced with learning some well-meaning (hopefully) soul’s bespoke framework that was maybe documented, but the docs are probably out of date, and the code’s been mangled by other folks who didn’t understand it, and all those people probably don’t even work there anymore. I’ve hit this is in every company I have worked for, even the smaller ones. I’ve worked on one enterprise application where there were multiple custom frameworks solving a single problem. Yes, people got sick of the old outdated version and just gave up on it, but it was so ingrained that they left it and just started the process all over again for new stuff (ah Reports and LegacyReports, how I do not miss you, although probably a bad example as I don’t think Ash has reporting yet). In a way, you can’t really blame them.
In any event, I hate this. The worst part is that many developers just accept that this as the way it is. If things are “just regular functions” they can at least hack it to pieces to achieve their immediate goal without having to worry about how it affects the next person. Many people who do this do it because it’s more fun than working on CRUD. Then when cracks start to show in their design, they don’t care because most people don’t spend more than 2-4 years at a single job so they’re gone and now it’s someone else’s problem. I realize not everyone is like this, but it’s a real thing I’ve witnessed real people say (sometimes they are even boastful about it—gross).
And of course I’m describing worst case here. Even when these things are done well, the cracks always start to form. Ash is developed by people whose only job is to make sure this stuff works and is flexible. I absolutely understand the initial pain of seeing something that looks alien but that pain is far less than what I feel when I find out I have to learn multiple in-house mini-frameworks solving different problems. All that to say, I would much rather put some time in up front learning a common, third party language than ever have to deal with a homegrown framework again.
And to be clear, I am someone who has made their fair share of these custom frameworks.
zachdaniel
Thank you for your feedback! I appreciate the kind words
I won’t personally “argue” with your takes really insofar as “convincing” people to use Ash coming from me has a pretty clear bias, but ultimately Ash isn’t a fit for every person or every project and that’s All Good™ ![]()
If you do end up switching your app off of Ash, please do come back with a retrospective, as I imagine that you will have lots of learnings from that process. Best of luck! ![]()
mudspot
I’m an early adopter of Ash.
The primary customer facing parts of our application stacks are all on the Phoenix Framework. Before our adoption of the Phoenix Framework, we were on React. The switch made our productivity 3x. Our productivity were further increased by another factor of 2 with the adoption of Ash.
There were 2 things which made me push for the use of Ash in all our projects.
- the ethos of “model your domain…”
While I’m an accomplished software engineer, my main way of thinking/solutioning is at the data engineering level, aka data domains. Ash made me feel home by allowing me to get back into my familiar mode of approaching solutions from the data engineering angle. - Policies
I have previously implemented data policies using Postgresql’s “CREATE POLICY”. Geesh, the nightmare of maintaining policies at the database layer. It’s my second hate after stored procedures.
Platforms like Supabase made policies easier. But not by much.
Ash’s implementation of Policies is gold!
I’ll also like a word about testing.
I don’t test against Ash framework. (Or any 3rd party frameworks)
I just assume they work.
Rather, I write tests to ensure that the data path (input and output) are what I expect them to be. That means again, I test the data engineering path.
(Of course, the rest of my tests are on UI / UX liveview testing)
Popular in Discussions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









