Wasp Configuration Language: Simplify Full Stack App Creation
What is Wasp?
Imagine modern monorepos. If you are not using typesafe solutions like tRPC
, chances are - you know the pain of synchronizing your types between the backend and front end.
More than that - you are probably also aware that creating new projects, endpoints, databases, scaffolding frontend, and backend is somewhat simplified nowadays compared to what it was 2-3 years ago, but still - one of the most tedious tasks there is. I for one am not interested in repeating the same thing I do for different projects. I want to write logic, I want to create products.
So, you can either turn to some pre-built by someone boilerplate, that either is open source and more often than not crappy and outdated, or a paid one, that is actively maintained but pricey. And even after that, it will be like learning a completely new codebase, to get the grip of the boilerplate ropes.
So what then, CLI, to scaffold our boilerplate? Something like T3? You could, but it's serverless stuff, that you might not necessarily need/want. What if you need a fully functioning backend + frontend?
Hold the door: here comes in Wasp - it's neither of those options listed above, but provides you with way more than just a boilerplate.
Wasp - is a configuration language, it's not a programming language. If you learned how to read the all-mighty JSON, you will be most likely able to grasp Wasp. I did - it means anyone can.
Ultimately, you create a file .wasp
and tell Wasp compiler:
what kind of endpoints you need, what they do (read or write);
what your database should look like
what your frontend routes should look like
what authentication methods do you want to use
...and hit the command in your terminal to generate a project, that does exactly that:
have all the stuff you need to be generated for you in a clear, unobfuscated way (you can navigate yourself in the generate output folder even)
creates a database for you
handles migrations
makes sure your frontend knows your backend types (full-stack type safety)
and many more things, that I have yet to discover myself!
Pretty neat project structure, from the get-go
Now that I am done selling it, let me tell you my initial thoughts about it and the project overall.
Initial feeling
I love engineering, new ideas, new projects and things related to DX. I find it pretty important to have good DX for the quality of the product's life (whatever product this is). If you have an excellent product but shitty, legacy code, that does not scale or is just a nightmare to maintain you are almost guaranteed to have trouble finding the right people to work on it (you will find people, but they will leave one way or another). Welp, that's just my belief, does not necessarily make it right.
This brings me to the point, that what Wasp seems to be aiming for is to gap the bridge backend and front, where anyone even with a minimum of experience in both fields can create full-stack apps. It spins up a nodejs server for you and handles DB connection, migrations, and data modeling (to a certain level of course). So, the goal is noble but I only have one fear - abstraction. Nowadays all our technology is abstracting so much from the basics (which is expected), that new people coming into the field can achieve the same projects/goals but have no idea how things work under the hood.
Abstraction simplifies development, but it also puts you in a very tricky position if things go wrong. And, you are no longer in control of your codebase/project. You depend on yet another tool, for this tool to do well and do the job correctly. If tomorrow there is a bug that nobody caught in this tool - your end users will be affected.
Getting started
Abstraction is one thing, but I like shiny new tools and this seems intriguing, so I jump over to the documentation "Get started" section.
All is clear until the Listing tasks, as it doesn't matter which language you are choosing for your app (JS vs TS)
As my choice is TS, when working on Listing tasks, the article only focuses on JS (which it says in its title, so no blame). But, I think that TS is a very important piece of info to include, so I was expecting the very same implementation shown in the same article, but in TS also. Instead, I had to find a "TypeScript support" separated where it is written how to implement this using TS. The example given in the TS article also derails from the JS article (focuses on plural tasks vs singular) so it's a bit confusing and hard to grasp at first.
Because really, the only difference between JS and TS implementations is one extra import statement:
import { GetTasks } from "@wasp/queries/types"
...and annotate the function with the type like so:
export const getTasks: GetTasks = async (args, context) => {
return context.entities.Task.find any();
};
Hence, I think it deserves a life in the same article :)
Hard to debug
When transitioned into listing tasks in React component, I encountered an error where TS could not find my getTasks
declaration.
Not only do I have no idea why this default export seems to be missing, but I can't also find the package /queries/*
to try to debug it (see if the file has been generated or not), and that's because my IDE is not able to Go To Definition
, while I can't find @wasp
package manually (in the .wasp
folder, in the src
folder).
In the end, I managed to find the folder where queries are being imported from, but no file in question, so had to turn to the community for help.
With help of the community (a dev and devrel, I believe) we managed to pin down what was happening and fix the issue. So just to be clear, my issue here is not with the bug itself, as this is just an implementation detail and I was trying to do weird things (like install react 18) but with the abstraction itself, which complicates the experience in case things go south.
And I am not sure if it's my LSP that messes up with me or something else entirely, but my LSP rarely messes with me, so I gave it a credit of trust and blamed abstraction.
Community
The guys are great, helpful, replying to questions openly and pretty fast. One of the guys ( @Vinny ) offered to jump on the call with me and the issue I had was resolved very fast, so that's dope! I can't stress enough how important it is to have good/proper relationships with your end user (via any way possible - support, account manager etc).
In this case, even if I am skeptical about the entire thing and I have hiccups on the way to what the project offers, I know that a bunch of people have got my back and are ready to jump on the call with me to resolve this straight away. Whereas, if I try another project/product, that offers the same or alternative idea, the chances are - I will just abandon the thing from the get-go and get back to the traditional way of building things.
Overall
By the time I reach the chapter on Updating the list, I find myself enjoying the simple experience there is. Especially I liked the fact that the query from the client side is automatically invalidated by the Wasp, therefore the data on the creation of new tasks updated itself automatically. This was unexpected but I didn't know I wanted this until I saw it ๐ There seems to be a conversation about this topic, where the dev team wants to allow overriding this behavior which I can see the importance of, but - it just worked.
It is dammmn fast. Like, the start and stop of the server are snappy, and the commands are fast. The client-side changes do take some time to refresh, and I wonder if this scales with the app, but the initial "behind the scenes" stuff seems to be fast. And again, the experience of creating different "endpoints" and functionality helps us move faster. Some cool
tRPC
stuff right there.Excited to try this out in a real project rather than a to-do list... just need to carve out some time for it to start. :D
Next
I have an idea that I would love to try Wasp out for, as it seems like a good fit for it. Initially, I wanted to use NextJS with tRPC for it, but it didn't go as planned (mainly because of Nextjs) due to how Google Auth works inside iframed applications (it just doesn't). So, I hope that more of a client-side authentication will be possible (like it's very easy with Firebase). This is where I will have a chance to try more authentication in Wasp, sending emails and deploying. ๐ค