I haven't used Bullet Train, but I've found their "Teams should be an MVP feature" blog post [1] a really great overview of how to model team structures in relational databases before. Worth a read!
nice! that's something i stumbled over when re-architecting a 2-sided marketplace (in rails) for one of my startups. the data model they describe is roughly what i ended up with, but it took some iterating to get there. the key understanding was that the relation table in a many-to-many relationship is not just a technical detail but encodes important information about real world systems, especially the human kind. as engineers, we get often get stuck on the entities being the important bits, but more often, the relations are where all the action is.
I really like Derrick Reimer's blog[0] for these types of posts. You might have to go back in time to find something a little more technical. On second glance, it seems the older articles are no longer available. You can find most of them[1] on the Wayback Machine though.
I'm glad alternatives like Alpine exist for small sites that don't need many additional behaviours. But having used Alpine for a medium-sized art gallery website last year, I can't really recommend it for anything larger than a very simple site. The fact that all your code is scattered as strings everywhere without error checking or types makes it really hard to debug and work with long-term.
For lightweight front-end tooling, nothing has unseated the ease of Preact for me.
I've been using AlpineJS on various projects for about one year. The creator (Caleb) is actually a Laravel developer and maintains the Livewire meta framework.
I find the sweet spot for utility frameworks like AlpineJS is when used in conjunction with server-side components [1]. For example, when designing server-side Blade components, the more you can keep within the component itself (e.g. html, styles, interactivity), the easier it is to reason about and maintain the component going forward. If your x-data function becomes unwieldy, consider moving the code to a separate Javascript function that returns an object and calling that function from x-data.
Ultimately, using tools like Alpine or Tailwind is a tradeoff. My apps tends to be relatively small and only managed by myself or a small team. If you're building large, front-end heavy apps; React, Vue, Svelte, etc. are definitely a better fit.
The use with Livewire is part of what makes it such an awesome tool to pair with Elixir LiveView. I mainly just need enough js to do client-side things (like closing/opening menus) and it's perfect for that.
I don’t know much about your project but these tools are really meant to be used in conjunction with “html over the wire” frameworks. IE, your JS has zero business or app logic and is just taking care of small UI concerns like transitions and showing modals. They scale just fine in these situations.
exactly this, and honestly, I feel like we need to get back to this model as an industry.
There are times when full-blown SPA is superior, but not nearly as often as people currently think. And the toolchains get vastly simpler when you're not doing SPA too.
Exactly. I used alpine in combination with django for a project and it quickly became a nightmare to maintain when alpine started to take care of app logic / SPA-type reactivity.
Alpine is just not designed with that sort of application in mind, nor should it be.
Funnily enough, I've avoided react/angular/vue as much as possible specifically because I've _always_ felt it was fundamentally the wrong approach. When I first discovered svelte my reaction was "thank god someone else sees it too".
Over the years I've moved further and further from the web as a result of that belief. I still do web work when needed and as a result I'm familiar with vue and angular but I actively try to avoid knowing any more about them than I absolutely need to for accomplishing the goal.
Coming from iOS, with their Massive ViewControllers, and the occasional (usually half-baked) MVVM, it didn’t seem that bad at first.
On the contrary; components!
Finally reusable pieces of UI! Try doing that when everyone on a team is hell-bent on their One Storyboard to Rule Them Al. Even if you did, @IBDesignable (used to preview components in Storyboards) would just crash anyway.
Instantaneous reloading! Even when it takes a bit of time, it takes less than 3 minutes. Pretty much instantaneous when coming from Xcode.
So, yes, React too was a pleasant surprise at first. The kind you get when you take of shoes that are just a tad too small.
So far, everything I’ve had to type in it was code specific to what I was doing. And that feels nice.
The extra boilerplate that doesn’t bring any value to me, as a dev, when needing to update values at runtime. I find two-way binding to just be simpler.
Same thing for the components and their props.
But I also get why some wouldn’t appreciate having things getting "automagically" done for them.
Not sure what part is confusing, Svelte and Vue have their own template languages inside HTML, I don't want to write another `v-for` or a `#if :else` instead of JS/TS.
I had the same feeling with Vue2-3 a while ago, I'd say Svelte is relatively similar in feelgood as both eliminate a lot of annoyances to create "leaner" components compared to React.
I've been using daisyui + svelte and I'm pretty happy with it so far. It may not be as rich as some of the react UI libraries but the basics are all there.
And for Alpine it's sort of fine. People have taken Alpine a lot further than the original intent, which is to add sprinkles of JS to what is otherwise a server rendered page.
For anything even slightly more complicated we have things like Mithril or Preact, and yeah they avoid this sort of thing for a reason.
I’m glad when tools like Alpine remain in their niche. Too many of them grow with their userbase, adding every requested feature, until they become as unwieldy as the framework they originally tried replacing. If you outgrow Alpine, migrate to another framework instead.
Then why not go with nextjs outright so you can apply the exact amount of interactivity for every little detail on your website without changing your entire setup halfway through.
Next.js is a fantastic solution if you're building a SPA.
Imagine I'm a very early stage startup so I start out with a simple app built on Laravel. All my engineers are relatively non-senior PHP folks, not great at JavaScript. So it's rendered server-side in PHP - easier to achieve enough performance, security, maintainability by leveraging the framework. Then I want to put some tiny bit of client-side interactivity. Going full SPA with Next.js would involve a lot of extra cost and complexity. jQuery and Alpine fit well into that niche, and Alpine particularly helps with reacting to state in a way that jQuery is hard.
I don't really understand why people want so bad to mix in code into HTML.
The whole fight since 2000 was to avoid doing that through minimalistic templating and naming elements semantically so you can attach the logic from outside.
That approach (i.e. the jquery style of attach logic to the DOM) just doesn't scale when you're writing a single page app where _everything_ needs to have JS logic attached to it. It turns into a complete mess of imperative UI twiddling and it's extremely easy to forget to update some little element in response to a change.
The bigger question IMHO is if you actually need a SPA. If you don't then yeah the old jquery style (now alpine.js or similar frameworks are spiritual successors) is perfectly fine.
Scaling comes from splitting your app into components and correctly mamaging staye not from the way you attach things to your view layer.
jQuery didn't scale because there was no recommend way to split it into components and managing state.
Those day Backbone.js was amazing innovation.
If jQuery came into existance today when we know what we know about components and their role in building large applications it would be perfectly suitable for many applications.
I agree with this, we managed to sometimes create SPAs faster even though we had to duplicate template/initial page logic on the server side for each page in case of direct link/page refresh. Nowadays sometimes figuring out which prop you misused from a 3rd party component based on a 100 lines TS error takes more time than the actual coding.
I wanted to use something light so I tried Preact without build tools. It was awful, nothing worked (like router and store), so I switched to Vue.js - where everything just worked out of the box. Not sure if I was just unlucky in my selection of js files, or what, but I can't recommend Preact from this experience.
This was a concern for me but when the Remote Ruby devs had the AlpineJS guy on last year, he mentioned that you can pull them apart into data components, which provides a separation that I found quite tidy. Did you check this out and find it unsatisfactory?
I did! I actually forgot about that feature when making the parent comment. It was a useful addition to a degree.
I used it for more complicated components like a mobile nav with animations, and for some re-usable pieces like a subscribe form. The downside with Alpine.data is that it splits the HTML from the JS, so developing and refactoring was a bit of a pain, and caused errors because of old variables I accidentally left in the HTML (whereas Preact/TSX would give me an in-editor error).
It also didn't really mitigate the need to wire up all the pieces your data component exposes into an HTML correctly. Though, this was working inside a simple PHP-based templating engine — maybe one that supports better snippets with parameters would make that part of the experience better.
I’ve made an Alpine plugin that can do a lot of the common things Unpoly does: https://imacrayon.github.io/alpine-ajax/ I’m actively working on it and looking for feedback.
I want to try building something with either and see if it works for me. But last time I couldn't decide between it and alpine and ended up using neither :/
agree with your comment.
i'm using alpine with django and it's is really nice.
some very small sites are using it in production like Vimeo (link:https://vimeo.com/customers/enterprise)
>> The fact that all your code is scattered as strings everywhere without error checking or types makes it really hard to debug and work with long-term.
I'm afraid this doesn't match my experience.
All your code can be in a single file (or as many as you want) with window.app = function(){return{show:false}}
You might find this overview of Windsor [1] interesting then. It was a classic typeface that many others (including Mackinac, used on Fly.io) were inspired by.
Glad you like it! The text styles are custom, and the layout is built using an in-house CSS framework not unlike Tailwind [1].
But if you'd like to build something similar, you could get pretty close by using something like Tailwind and building with Rasmus Andersson's lovely (and open-source!) Inter type family [2], which we use throughout the site.
thanks for your reply and great work:). The site looks just amazing and very clean (especially typography). I noticed it uses utility classes like tailwindcss so thought maybe there is a similar library.
A bit tangential, but I tried sharing this link with a few friends on Facebook Messenger, and noticed it's blocked because it "violates Community Standards" [1]. Even shortened bit.ly links are blocked.
Anyone know why that would be the case? I'm trying to not assume malice (eg. maybe it got misflagged?) but it certainly feels like censoring and is yet another push for me to drop Messenger too.
[1]: https://blog.bullettrain.co/teams-should-be-an-mvp-feature/