State of Greenwood (2025)
Published: Dec 19, 2025

Looking back on this past year since our previous end of year post (opens in a new window), the Greenwood team held true to its promise in ensuring a broad set of ecosystem compatibility around import map generation, hosting adapters, and package managers, as well as continuing our participation in related standards and community groups. Greenwood was even featured in the latest episode of Shop Talk Show (opens in a new window)!
For component libraries, you can see demonstrations of using Greenwood with Spectrum Web Components (opens in a new window), the USWDS (opens in a new window), and Web Awesome (opens in a new window). These demonstration projects helped further refine and validate Greenwood's capabilities for generating import maps, inlining and bundling of CSS, and supporting the most popular package managers in the ecosystem; all in the pursuit of making sure you can always use your favorite library with Greenwood as simply as running npm i. In addition, we've created demonstration repos for using Greenwood with tRCP (opens in a new window) and Lume (opens in a new window) (still dependent on upcoming features coming in our v0.34.0 (opens in a new window) release).
On the community side, we were happy to see the WinterCG graduate and become an official ECMA Technical Committee group (opens in a new window) as the WinterTC(55) (opens in a new window). Promoting standards for both the web and sever-side JavaScript runtimes is a valuable and meaningful vision and effort for the Greenwood team, and we are happy to participate and contribute to the WinterTC and the WCCG (Web Components Community Group) (opens in a new window).
We hope these initiatives and improvements over the past year have worked to make Greenwood even better for building websites so please feel free to share your thoughts and feedback with us.
Now, on to the year in review! 👇
The Year In Review
TypeScript Support
Greenwood now provides built-in support for TypeScript, with the ability to fallback to using tsc if certain TypeScript features you're using (like Decorators, enums, namespaces, etc (opens in a new window)) are not supported through just type stripping alone. This was motivated in part due to NodeJS adding TypeScript (type-stripping) support out of the box. This means you can write your entire project, including SSR pages and API routes, entirely in TypeScript with no configuration required!
This also means that you can author your Greenwood configuration files and plugins with TypeScript too:
// greenwood.config.ts
import type { Config } from "@greenwood/cli";
const config: Config = {
// ...
};
export default config;
For actual type-checking, below is Greenwood's recommended tsconfig.json settings so that you can get full IDE support and so that you can run tsc during CI.
{
"compilerOptions": {
// minimum required configuration
"target": "es2020",
"module": "preserve",
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"noEmit": true,
// additional recommended configuration
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"verbatimModuleSyntax": true,
"erasableSyntaxOnly": true,
},
"exclude": ["./public/", "./greenwood/", "node_modules"],
}
Check out our TypeScript docs to learn more about getting setup with TypeScript and Greenwood.
New Project Scaffolding
The Init scaffolding CLI got an major overhaul this year, moving to a more robust, prompt based experience that will walk you through a number of options for creating and customizing your next Greenwood project. Now, when scaffolding out a new Greenwood project, you're able to specify the name / output directory, support for TypeScript, and package manager.
It's as easy as running:
$ npx @greenwood/init@latest
Read the docs to get started with your next Greenwood project today.
AWS Adapter
This year we released an official adapter plugin for generating Lambda compatible function code for your SSR pages and API routes with AWS. ☁️
Simply install the plugin and add it to your Greenwood config file:
import { greenwoodPluginAdapterAws } from "@greenwood/plugin-adapter-aws";
export default {
plugins: [greenwoodPluginAdapterAws()],
};
Taking into consideration that there are many methods and options for deploying to AWS, this adapter plugin is primarily focused on generating consistent and predictable build output that can be complimented by some form of IaC (Infrastructure as Code) (opens in a new window) or deployment tooling of your choice. The build output will look similar to Greenwood's own standard build output and will be available in the .aws-output/ folder at the root of your project after running the build command.
To learn more, you can read our v0.32.0 release blog post (opens in a new window) and checkout the docs (opens in a new window) to get started.
The Year Ahead
As the team looks to the coming year ahead, we're currently in progress on the next Greenwood release; v0.34.0 (opens in a new window), which we aim to release with a key feature; dynamic routes! Dynamic routes will allow file-system based routing like below for serving dynamic routing paths, and will be supported by all our serverless adapter plugins:
src/
pages/
blog/
[slug].js
This would serve any number of the following routes:
/blog/my-first-post//blog/my-second-post/- etc
Additionally, and although dependent on compatibility and upstream needs on these platforms and runtimes, we are actively working on Bun runtime support as well as an official Cloudflare adapter. Both of these are in various stages of development and testing, and we hope to close out our current ecosystem milestone by delivering on them in some capacity.
Lastly, and already supported in WCC (opens in a new window), TSX support will be coming to Greenwood for scripts and SSR pages, enabling JSX for templating through a custom render function, enabling type-safe HTML!
export default class Card extends HTMLElement {
selectItem() {
alert(`selected item is => ${this.title}!`);
}
connectedCallback() {
if (!this.shadowRoot) {
this.thumbnail = this.getAttribute("thumbnail");
this.title = this.getAttribute("title");
this.attachShadow({ mode: "open" });
this.shadowRoot.adoptedStyleSheets = [sheet];
this.render();
}
}
render() {
const { thumbnail, title } = this;
return (
<div class="card">
<h3>{title}</h3>
<img src={thumbnail} alt={title} loading="lazy" width={200} height={200} />
<button onclick={this.selectItem}>View Item Details</button>
</div>
);
}
}
customElements.define("x-card", Card);
You can see a preview of this upcoming work in this demonstration repo (opens in a new window).
In Closing
The Greenwood team is very eager to wrap up our current efforts to release v0.34.0 and continue our ongoing march towards a 1.0 release (opens in a new window). Greenwood wants to be there every step of the way to help you get the most out of the web and ensure you have full ownership of your code and content. From SPA to SSG to SSR and everything in between, building vanilla or with friends, we want Greenwood to run wherever the web can run so the choice can always be yours.
Please come join us on GitHub (opens in a new window) and Discord and we can't wait to see what you build with Greenwood!