Skip to main content

Blog

We're excited to announce the release of Root v3.0, which is centered around — you guessed it (cue more em dashes, please) — AI! With this release, Root AI gains enhanced intelligence capabilities with reasoning and logic, tools for reading and writing directly to the CMS, and the ability to choose from many compatible LLM providers, including self-hosted ones!

In addition, this release includes a few major upgrades: a brand-new JSX renderer built into Root, updates to the Root CMS authoring experience, and a faster build pipeline under the hood.

This post walks through what's new and the handful of migration steps to be aware of.

Root AI: streaming, reasoning and logic, and tool calling

Root AI has been rewritten from the ground up with a new streaming API (improving token response times), reasoning and logic (with planning and execution modes), and tool calling (which allows Root AI to read and write directly to the CMS).

Configuration has graduated from "experimental" and moves to a new top-level ai plugin option, and you can register one or many models across different providers. For example:

ts
cmsPlugin({
  ai: {
    models: [
      {
        id: 'claude-opus-4-7',
        label: 'Claude Opus 4.7',
        provider: 'anthropic',
        apiKey: process.env.ANTHROPIC_API_KEY,
        capabilities: {tools: true, reasoning: true, attachments: true},
      },
      {
        id: 'gpt-5.5',
        label: 'GPT-5.5',
        provider: 'openai',
        apiKey: process.env.OPENAI_API_KEY,
      },
      {
        id: 'gemini-3.1-pro',
        label: 'Gemini 3.1 Pro',
        provider: 'gemini',
        apiKey: process.env.GEMINI_API_KEY,
      },
    ],
    defaultModel: 'claude-opus-4-7',
  },
});

A visual refresh

The Root CMS UI received a style refresh. We plan to add support for customized themes soon — stay tuned!

Permission groups

Root v3.0 allows greater access granularity and organization through permission groups.

Within a permission group, you can assign a role to all users in the group, and optionally restrict their access to one or more collections. This makes it easy to give, say, a blog editorial team EDITOR access on just their collections without granting them the run of the project.

Component picker UI

Within the CMS, there is a new "picker" variant that presents content editors with a more visual way of selecting content to add to their site, including support for "presets" that autofill templated data with commonly used field values.

Developers can use the component picker by adding {variant: 'picker'} to schema.oneOf() fields. For example:

ts
schema.oneOf({
  id: 'block',
  variant: 'picker',
  types: [HeroSchema, GallerySchema],
});

// Hero.schema.ts
export default schema.define({
  name: 'Hero',
  image: '/cms/previews/hero.png',
  presets: [
    schema.preset<HeroFields>({
      id: 'big',
      label: 'Big hero',
      data: {title: 'Welcome', layout: 'wide'},
    }),
  ],
  fields: [...],
});

For projects where the "picker" variant is preferred as the default, set defaultOneOfVariant:

ts
cmsPlugin({
  defaultOneOfVariant: 'picker',
});

Task manager (experimental)

We're experimenting with a new task manager built right into the CMS to provide better project management capabilities directly in the UI.

In the future, we envision the task manager to be used as an entrypoint for coordinating tasks and reviews with Root AI and humans alike, so we're very excited to continue to develop and refine this feature.

To opt-in to the experiment:

ts
cmsPlugin({
  experiments: {taskManager: true},
});

Vite 8

Under the hood, we've updated Root's 3rd party dependencies to the latest verions. The biggest change is the update to Vite 8, which switches its bundler from rollup to rolldown.

As far as we know, the update to Vite 8 should be backwards compatible other than deprecation warnings to rename the config from "rollupOptions" to "rolldownOptions".

Learn more about Vite 8 at: https://vite.dev/blog/announcing-vite8

A native JSX renderer

Root now ships with its own JSX renderer (@blinkk/root/jsx). It exposes a Preact-compatible API so existing components, contexts, and islands keep working without changes. The difference is what happens at render time: Root walks the VNode tree itself, with first-class understanding of custom-element tag formatting, script/style ordering, and Root's own context propagation.

In practice, this means cleaner HTML output, a much smaller server-side dependency footprint, and a renderer that we can keep evolving alongside the rest of Root.

Opt in by adding jsxRenderer to root.config.ts:

ts
export default defineConfig({
  jsxRenderer: {
    mode: 'pretty',
    blockElements: ['my-card', 'my-section'],
  },
});

Plugin pods

Pods are a new way for plugins to bundle a chunk of a Root project — routes, elements, bundles, collections, translations, even custom Vite plugins — and reuse it across sites. Drop a pod into a project's root.config.ts and its routes are mounted, its elements and bundles are auto-registered, and (for CMS projects) its collections show up in the CMS sidebar.

Pods make it dramatically easier to share design systems, marketing-page templates, and reusable CMS schemas across teams.

ts
import blogPod from '@third-party/blog-pod';

export default defineConfig({
  plugins: [
    blogPod(),
  ],
});

Notifications hooks

Plugins can now hook into Root's notifications service to provide users with timely updates as actions occur throughout the system, such as subscribing to email and Slack notifications when changes are published.

ts
cmsPlugin({
  notifications: [
    {
      id: 'team-notifier',
      label: 'Team notifier',
      onAction: async (ctx, action) => {
        if (action.action === 'doc.publish') {
          // ...send a notification.
        }
      },
    },
  ],
});

Installation

Root v3.0 is available now on npm and is installable using the package manager of your choice.

sh
pnpm add @blinkk/root@latest @blinkk/root-cms@latest

Migration notes

A v2 → v3 migration is mostly a package install and a config tweak. The pieces to be aware of:

  • Vite 8: Rename build.rollupOptions to build.rolldownOptions in any custom Vite config.

  • JSX renderer: Optional. To opt in, add jsxRenderer: {mode: 'pretty'} to root.config.ts. The renderer is API-compatible, so no component changes are required.

  • Root AI config: Move from experiments.ai: {endpoint, model, ...} to the top-level ai: {models: [...]} shape.

The full breakdown is in packages/root/CHANGELOG.md and packages/root-cms/CHANGELOG.md.

Thank you!

Huge thank you to all the Root users who tested the alpha/beta builds and filed bugs and feature requests. Root is continually improving and we have so many more big features planned ahead.

Issues, ideas, and PRs are always welcome at github.com/blinkk/rootjs.

Introducing Root.js

2024-04-01

When we started Blinkk in 2014, we sought to streamline web development in a way that would scale for websites of any level of complexity. We wrote a blog post called “All I want to do is build a website (and launch it)” detailing some of the challenges we faced, and after re-reading it ten years later, most of those challenges are still true today:

  • Launches involve a myriad of people working together to produce the final site: designers, developers, copywriters, marketing, product, graphic artists, translators, and animators. Modern web site production needs to be rapid, collaborative, social – because there are often many people and many stakeholders involved throughout the process.

  • Web development can involve dozens of different technologies that are constantly evolving. Ten years ago, Python was our preferred programming language; today, TypeScript has reigned supreme. JSX is also as popular as ever, with many frontend frameworks adopting some variant of it. Modern browsers are also constantly shipping new APIs that reduce the need for custom 3rd-party libraries. We don't know what the ecosystem will look like in another ten years, but we do know our tools need to adapt to them without the need to constantly rework our infrastructure.

  • Content editing, reviews, and publishing need to be collaborative, easy, and painless. Nobody wants to be up at 4AM to launch a site, and if there are any content mistakes, they need to be addressed as quickly as possible.

A few years ago, we noticed our tooling and processes weren't keeping pace with the rapidly evolving modern ecosystem and were no longer tenable to our needs. Tools like React, Next.js, esbuild, and Vite were on the rise, while we were on what felt like a dying stack, constantly debugging slow and complex webpack configurations using a legacy Python2 / jinja based-tool that was quickly reaching EOL.

So we sat down and started to diagram what our "infrastructure of the future" would look like. This is what we whiteboarded:

site infra system design: requirements and examples
An overview of our site infrastructure and tools requirements.

After several months of testing out new technologies (including Astro and Next.js) to see if they would work for our projects (which we will write about in a future blog post), we quickly realized we needed something tailored to our internal processes, development patterns, and client requirements. We worked tirelessly for the past two years to produce what you see in front of you.

Today we're excited to introduce two new tools we've created to help solve many of the problems we've faced with web development: Root.js and Root CMS. Among their many features include the following:

  • Zero JS sent to the browser. The TSX components render HTML only and do not automatically rehydrate – interactive elements can be added via web components.

  • First-class support for web components. Interactive islands are all based on custom elements, written in the framework of your choosing (or no framework at all). The system intelligently figures out which custom elements your page uses and injects the matching file dependency from elements/<tag-name>.ts.

  • Localization is built-in. No more needing to download additional plugins to get translations to work. Routes are all locale-aware.

  • Root CMS as an optional plugin. The CMS runs the same in local development as it does in production. And since schemas are written as TypeScript files, developers can test and verify schema changes in a local environment before deploying to production.

    • CMS Features include: collaborative editing, component-centric page building, instant previews, scheduled publishing, user-defined authentication, translations import/export from Google Sheets, and version history.

We will share more details about how and why we've created these tools over the upcoming weeks/months, but in the meantime, we hope that you'll explore the website, check out the guide, and share any feedback with us in GitHub.

1
2
3
4
5
6
7
8
9
10
11
12
Breakpoint: