Skip to content

Commit 801e316

Browse files
authored
Merge branch 'release' into filip-release-0.20.1
2 parents 7ab86c7 + 021f8e7 commit 801e316

File tree

18 files changed

+801
-276
lines changed

18 files changed

+801
-276
lines changed
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
---
2+
title: "Wasp 2025: Year in Review"
3+
authors: [matijasos]
4+
image: /img/year-review-2025/banner.png
5+
tags: [wasp, year-review, launch-week]
6+
---
7+
8+
import { ImgWithCaption } from './components/ImgWithCaption';
9+
10+
2025 was both the biggest year for Wasp so far, but also one in which we were heads-down building the most. While we shipped consistently throughout the year (5 launch events, 20 blog posts & tutorials, and a steady stream of features) the real story is what happened beneath the surface: **clearing the path to 1.0**.
11+
12+
{/* truncate */}
13+
14+
This was the year in which we had to slow down in order to speed up. We got serious about maturity, transparency, and building the foundation for what Wasp needs to become. Still, we managed to sneak in a few cool new features, too.
15+
16+
We want to share with you what we achieved, what we learned, and what's coming next.
17+
18+
## 2025 in Numbers
19+
20+
- 📦 **13 releases** (v0.16 → v0.20)
21+
- 🚀 **5 launch events**
22+
-**+8,182 [GitHub](https://github.com/wasp-lang/wasp) stars** across Wasp and Open SaaS
23+
- 🔀 **489 pull requests merged**
24+
-**284 issues closed**
25+
- 👾 **4,669 Discord members**
26+
- 🐝 **8 people** working on Wasp full-time (welcome Franjo, Carlos & Tole!)
27+
28+
## What We Shipped
29+
30+
In 2025, we hosted **five launch events** - one each quarter, plus a special Xmas launch. You can see the details of each launch below:
31+
- [**Launch Week 8**](/blog/2025/01/09/wasp-launch-week-8) (January) - "Fixer Upper"
32+
- [**Launch Week 9**](/blog/2025/04/09/wasp-launch-week-9) (April) - "The Road to 1.0"
33+
- [**Launch Week 10**](/blog/2025/07/07/wasp-launch-week-10) (July) - "Public Exposure"
34+
- [**Launch Week 11**](/blog/2025/09/28/wasp-launch-week-11) (September) - "Grinding the Grind"
35+
- [**Wasp Xmas Launch**](/blog/2025/12/17/wasp-xmas-launch) (December) - React 19, Claude Code Plugin, Polar
36+
37+
What we released falls into four major categories:
38+
- **Core & Developer Experience** - the overall architecture, CLI, and what/how Wasp uses under the hood
39+
- **Integrations & Ecosystem** - how well Wasp plays with other tools and services (deployment, analytics, AI, ...)
40+
- **Open SaaS** - an open-source SaaS boilerplate starter, based on Wasp. Payments, admin dashboard, emails, and more
41+
- **Content & Education** - tutorials, guides, showcases, and community engagement
42+
43+
Let's now dive into the details of each category:
44+
45+
### Core & Developer Experience
46+
47+
<ImgWithCaption
48+
alt="Wasp Roadmap on GitHub"
49+
source="img/year-review-2025/roadmap.png"
50+
caption="Wasp's roadmap to 1.0 is on GitHub"
51+
/>
52+
53+
- **React 19 & stack upgrades** - Updated to React 19, along with Node.js and Vite version bumps
54+
- **Public development roadmap** - Published our [transparent path to 1.0](/blog/2025/07/14/public-wasp-dev-roadmap), with epics and milestones [tracked on GitHub](https://github.com/orgs/wasp-lang/projects/5)
55+
- **Deployment docs rehaul** - New guides for [Coolify, CapRover](/docs/deployment/deployment-methods/self-hosted), and improved deployment story overall
56+
- **[TypeScript config](/docs/general/wasp-ts-config) (experimental)** - Define your app in `main.wasp.ts` instead of the DSL, with full editor support out of the box. Soon to become the default.
57+
- **Quality of life improvements** - Env variable validation with Zod, [`wasp build start`](/docs/deployment/local-testing) for testing production builds locally, better TSConfig behavior
58+
59+
While some of these look like single bullet points, the roadmap and TypeScript config alone represent months of focused work. Behind the scenes, we also [overhauled our internal architecture](/blog/2025/07/18/faster-wasp-dev) - modernizing how we build, test, and release Wasp, so we can move faster and ship with more confidence.
60+
61+
This groundwork is already enabling us to make Wasp behave more like a "standard" part of the JS ecosystem: respecting your existing tooling, playing nicely with other libraries (e.g. ShadCN), and just working the way you'd expect.
62+
63+
### Integrations & Ecosystem
64+
65+
- **Railway CLI Integration** - One-command deployment to Railway with `wasp deploy railway launch`
66+
- **Claude Code Plugin** - AI-assisted development with [deep Wasp integration](/blog/2025/12/23/wasp-claude-code-plugin)
67+
- **AI-friendly docs** - Added .cursorrules and llms.txt with versioning, so AI tools always have the right docs for your Wasp version
68+
- **[Slack Authentication](/docs/auth/social-auth/slack)** - New auth provider, next to Google, GitHub, Discord, and others
69+
70+
No tool can exist in isolation. And when we find a service/tool that fits with Wasp's philosophy, we go above and beyond to make it easy to use together.
71+
72+
### Open SaaS
73+
74+
<ImgWithCaption
75+
alt="Open SaaS"
76+
source="img/year-review-2025/open-saas.png"
77+
/>
78+
79+
2025 is the year Open SaaS truly came into its own. What started as a simple wrapper around Wasp with common SaaS features has grown into a fully-fledged product. It's now one of the most common ways developers start their (Wasp) apps.
80+
81+
- **Hit [13,000+ GitHub stars](https://github.com/wasp-lang/open-saas)** - One of the most popular React/Node.js SaaS starters
82+
- **Complete redesign (v2.0)** - Now with ShadCN UI, and a sleek new design by default
83+
- **Railway Marketplace** - Now part of [Railway's official marketplace](https://railway.com/deploy/open-saas). One click deployment to Railway's hosting platform.
84+
- **Polar integration** - New billing provider, next to Stripe and LemonSqueezy
85+
86+
Open SaaS now also has its own [roadmap](https://opensaas.sh/#roadmap), developed in parallel with Wasp's roadmap. You're welcome to join, comment, and contribute - we'd love to have you!
87+
88+
### Content & Education
89+
Launch Weeks are our most intense publishing periods, but we don't go quiet in between. We aim to keep you up to date with Wasp's progress while sharing what we're learning along the way.
90+
91+
**Most popular deep-dives:**
92+
- [How we test a web framework](/blog/2025/10/07/how-we-test-a-web-framework)
93+
- [Cleaning up 5 years of tech debt in a full-stack JS framework](/blog/2025/07/18/faster-wasp-dev)
94+
95+
**Most popular tutorials:**
96+
- [Building Advanced React Forms Using React Hook Form, Zod and Shadcn](/blog/2025/01/22/advanced-react-hook-form-zod-shadcn)
97+
- [A Gentle Introduction to Database Migrations in Prisma](/blog/2025/04/02/an-introduction-to-database-migrations)
98+
- [How to Run CRON Jobs in Postgres Without Extra Infrastructure](/blog/2025/05/28/how-to-run-cron-jobs-in-postgress-without-extra-infrastructure)
99+
- [Build an agent-powered SaaS with Mastra AI & Wasp](https://www.youtube.com/watch?v=-mWmIaJ6AJk) (video)
100+
- [Vibe Code a Full-stack App Effectively](https://www.youtube.com/watch?v=WYzEROo7reY) (video)
101+
102+
## What We Learned
103+
104+
### Developers *really* want "Rails for JS" - productivity and portability
105+
106+
<ImgWithCaption
107+
alt="Rails for JS"
108+
source="img/year-review-2025/rails-for-js.png"
109+
/>
110+
111+
The JavaScript ecosystem is incredibly powerful - its modularity means there's a package for everything. But that same modularity makes it exhausting to start and maintain a full-stack project. You have to choose your bundler, your router, your ORM, your auth library/service, your hosting platform... and then keep them all working together as they evolve.
112+
113+
We've heard this over and over again: developers want the productivity and portability of Rails, but in the JavaScript/TypeScript world they already know. This conviction has only grown stronger for us in 2025 - there's a real gap here, and we're building to fill it.
114+
115+
### Frameworks matter more in the age of AI, not less
116+
117+
Here's something we've assumed for a while but haven't seen confirmed until recently: AI coding assistants work dramatically better with opinionated frameworks. When there's one right way to do something, AI can nail it. When there are fifteen ways to wire up authentication, it's another point of friction you or your LLM need to think about and make a decision.
118+
119+
We're literally seeing this as a choosing criteria now for Wasp - developers pick tools that make their AI assistants more effective. Good abstractions aren't just nice for humans anymore; they're essential for AI too. This has reinforced our belief that the right level of abstraction is one of the most valuable things a framework can provide.
120+
121+
### TypeScript is the way
122+
123+
We're moving from a DSL to TypeScript config. From "Wasp language" to "Wasp framework." Some of this is messaging, but it's actually a meaningful shift.
124+
125+
TypeScript gives an editor support for free - autocomplete, type checking, refactoring tools - without us having to build and maintain custom IDE plugins. It's a language developers already know. And it opens the door to more flexibility while keeping the benefits of a structured, declarative config.
126+
127+
This move reflects a broader lesson: meet developers where they are. Don't ask them to learn something new unless it provides clear, significant value. TypeScript config is just as expressive as our DSL (even more), but without the learning curve.
128+
129+
### Developers are building real businesses and tools
130+
131+
2025 made something crystal clear: Wasp has moved past the "toy/side project" phase. We're seeing developers build very real things - production apps serving actual users, internal tools at enterprises, startups that have raised funding, and yes, even exits.
132+
133+
This shift is meaningful. It's one thing to hear "I built a to-do app with Wasp" and quite another to hear "we're running our entire company on it." The maturity of what people are building now - and the trust they're placing in the framework - is something we don't take lightly. It's also the ultimate validation that we're on the right track.
134+
135+
## The Team
136+
137+
<ImgWithCaption
138+
alt="The Wasp Team"
139+
source="img/year-review-2025/wasp-team.jpeg"
140+
caption="The Waspeteers! This was at our annual retreat in Heidelberg we took in October. Banana juice with beer, anyone?"
141+
width="650px"
142+
/>
143+
144+
This is the team that made it all happen in 2025. Without their focus and dedication, none of this would be possible. This year we welcomed [Franjo](/blog/2025/03/20/meet-franjo-engineer-at-wasp), [Carlos](/blog/2025/04/07/meet-carlos-engineer-at-wasp), and another Matija (Tole). It is a unique privilege to be able to pick (and get picked by) your own team and get to design our team culture as we build out the vision we have for Wasp.
145+
146+
What we're building hasn't really been done before - a true full-stack, batteries-included framework for JavaScript. That means we're often in uncharted territory. Our work takes a lot of research and design before we can even start writing code. What keeps us going is the feedback and adoption we see from the community - knowing that what we're building actually helps people ship and achieve their dreams and goals.
147+
148+
## What's Coming Next
149+
150+
### Laser focus on 1.0
151+
152+
The path is clear and we're going full speed. Everything we did in 2025 - the roadmap, the internal refactors, the testing infrastructure - was setting the stage for this. Now we execute.
153+
154+
### Doubling down on AI
155+
156+
We're seeing exciting signal on how well Wasp works with AI coding assistants. Opinionated frameworks and AI are a natural fit, and we want to lean into that even more - better tooling, better docs, better integrations.
157+
158+
### Polishing the DX + more user-facing features
159+
160+
Having invested in leveling up the core of Wasp in 2025, we can now reap the benefits and move to the next stage - building cool features you'll see and use! We'll be doing a complete "DX audit", from creating a new project to building and testing it and finally deploying it to production.
161+
162+
## Thank you!
163+
164+
None of this would have been possible without you - our community. You're the ones building with Wasp, pushing its limits, reporting bugs, suggesting features, and showing us what's possible. Seeing you get excited about what we're building, and then taking it even further than we imagined, is what keeps us going.
165+
166+
Thank you for being part of this journey. Here's to a buzzing 2026.

web/docs/advanced/email/email.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ MAILGUN_API_URL=https://api.eu.mailgun.net
146146

147147
### Using the SendGrid Provider {#sendgrid}
148148

149+
:::caution SendGrid Free Plan Retired
150+
As of May 27, 2025, SendGrid has [retired its free plans](https://www.twilio.com/en-us/changelog/sendgrid-free-plan). A paid SendGrid plan is now required to send emails. Consider using [Mailgun](#mailgun) or [SMTP](#smtp) with another provider if you need a free tier option.
151+
:::
152+
149153
Set the provider field to `SendGrid` in your `main.wasp` file.
150154

151155
```wasp title="main.wasp"
@@ -161,7 +165,7 @@ Then, get the SendGrid API key and add it to your `.env.server` file.
161165

162166
#### Getting the API Key
163167

164-
1. Go to [SendGrid](https://sendgrid.com/) and create an account.
168+
1. Go to [SendGrid](https://sendgrid.com/) and create an account (paid plan required).
165169
2. Go to [API Keys](https://app.sendgrid.com/settings/api_keys) and create a new API key.
166170
3. Copy the API key and add it to your `.env.server` file.
167171

web/docs/project/testing.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ You can see some tests in a Wasp project [here](https://github.com/wasp-lang/was
102102
<TabItem value="js" label="JavaScript">
103103
```js title="src/helpers.js"
104104
export function areThereAnyTasks(tasks) {
105-
return tasks.length === 0;
105+
return tasks.length !== 0;
106106
}
107107
```
108108

@@ -122,7 +122,7 @@ You can see some tests in a Wasp project [here](https://github.com/wasp-lang/was
122122
import { type Task } from "wasp/entities";
123123
124124
export function areThereAnyTasks(tasks: Task[]): boolean {
125-
return tasks.length === 0;
125+
return tasks.length !== 0;
126126
}
127127
```
128128

@@ -152,7 +152,7 @@ You can see some tests in a Wasp project [here](https://github.com/wasp-lang/was
152152
{tasks &&
153153
tasks.map((task) => (
154154
<li key={task.id}>
155-
<input type="checkbox" value={task.isDone} />
155+
<input type="checkbox" checked={task.isDone} />
156156
{task.description}
157157
</li>
158158
))}
@@ -206,7 +206,7 @@ You can see some tests in a Wasp project [here](https://github.com/wasp-lang/was
206206
{tasks &&
207207
tasks.map((task) => (
208208
<li key={task.id}>
209-
<input type="checkbox" value={task.isDone} />
209+
<input type="checkbox" checked={task.isDone} />
210210
{task.description}
211211
</li>
212212
))}
@@ -271,7 +271,7 @@ You can see some tests in a Wasp project [here](https://github.com/wasp-lang/was
271271
{tasks &&
272272
tasks.map((task) => (
273273
<li key={task.id}>
274-
<input type="checkbox" value={task.isDone} />
274+
<input type="checkbox" checked={task.isDone} />
275275
{task.description}
276276
</li>
277277
))}
@@ -332,7 +332,7 @@ You can see some tests in a Wasp project [here](https://github.com/wasp-lang/was
332332
{tasks &&
333333
tasks.map((task) => (
334334
<li key={task.id}>
335-
<input type="checkbox" value={task.isDone} />
335+
<input type="checkbox" checked={task.isDone} />
336336
{task.description}
337337
</li>
338338
))}

web/docusaurus.config.ts

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type * as Preset from "@docusaurus/preset-classic";
22
import type { Config, DocusaurusConfig } from "@docusaurus/types";
33
import { themes } from "prism-react-renderer";
4+
import { SCRIPT_WITH_CONSENT_TYPE } from "./src/lib/cookie-consent";
45
import autoImportTabs from "./src/remark/auto-import-tabs";
56
import autoJSCode from "./src/remark/auto-js-code";
67
import codeWithHole from "./src/remark/code-with-hole";
@@ -238,29 +239,62 @@ const config: Config = {
238239
],
239240
};
240241

242+
type DocusaurusScript = DocusaurusConfig["scripts"][number];
243+
type ScriptWithConsent = Exclude<DocusaurusScript, string> & {
244+
requiresConsent: boolean;
245+
};
246+
241247
function getScripts() {
242-
const sharedScripts: DocusaurusConfig["scripts"] = [
243-
"/js/fix-multiple-trailing-slashes.js",
248+
const sharedScripts: ScriptWithConsent[] = [
249+
{
250+
src: "/js/fix-multiple-trailing-slashes.js",
251+
requiresConsent: false,
252+
},
244253
];
245254

246-
const devOnlyScripts: DocusaurusConfig["scripts"] = [];
255+
const devOnlyScripts: ScriptWithConsent[] = [];
247256

248-
const prodOnlyScripts: DocusaurusConfig["scripts"] = [
249-
{ src: "/scripts/posthog.js", defer: true },
250-
// Using Cloudflare Workers to proxy the analytics script
257+
const prodOnlyScripts: ScriptWithConsent[] = [
251258
{
259+
// We are using Cloudflare Workers to proxy the Plausible script.
252260
src: "/waspara/wasp/script.js",
253261
defer: true,
254262
"data-domain": "wasp.sh",
255263
"data-api": "/waspara/wasp/event",
264+
// Plausible doesn't use cookies, so it can be loaded right away.
265+
requiresConsent: false,
266+
},
267+
{
268+
src: "/scripts/posthog.js",
269+
defer: true,
270+
requiresConsent: true,
271+
},
272+
{
273+
src: "/scripts/reo.js",
274+
defer: true,
275+
requiresConsent: true,
256276
},
257277
];
258278

259-
if (isProduction) {
260-
return [...sharedScripts, ...prodOnlyScripts];
261-
} else {
262-
return [...sharedScripts, ...devOnlyScripts];
263-
}
279+
const scripts = [
280+
...sharedScripts,
281+
...(isProduction ? prodOnlyScripts : devOnlyScripts),
282+
];
283+
284+
return mapToDocusaurusScripts(scripts);
285+
}
286+
287+
function mapToDocusaurusScripts(
288+
scripts: ScriptWithConsent[],
289+
): DocusaurusScript[] {
290+
return scripts.map(({ requiresConsent, ...rest }) => ({
291+
...rest,
292+
// Scripts requiring consent shouldn't be loaded until the cookies are accepted,
293+
// so we use a custom type on the script _not to load it_ automatically.
294+
// Later, if cookies are accepted, the script will be loaded by the
295+
// `src/components/CookieConsentBanner.tsx` component.
296+
...(requiresConsent ? { type: SCRIPT_WITH_CONSENT_TYPE } : {}),
297+
}));
264298
}
265299

266300
export default config;

web/package-lock.json

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"prism-react-renderer": "^2.4.1",
3737
"prismjs": "^1.29.0",
3838
"react": "^19.1.0",
39+
"react-cookie-consent": "^10.0.0",
3940
"react-dom": "^19.1.0",
4041
"react-feather": "^2.0.10",
4142
"react-modal": "^3.14.3",

0 commit comments

Comments
 (0)