Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Cobalt 2.0 #201

Open
drwpow opened this issue Feb 26, 2024 · 9 comments
Open

✨ Cobalt 2.0 #201

drwpow opened this issue Feb 26, 2024 · 9 comments
Labels
enhancement New feature or request help wanted Extra attention is needed question Further information is requested

Comments

@drwpow
Copy link
Collaborator

drwpow commented Feb 26, 2024

Planning for Cobalt 2.0 is underway!

Many wonderful people have put Cobalt through the ringer. While I’ve gotten lots of confirmation Cobalt is on the right track working with DTCG tokens, there’s still more needed from it. So to address that, I’ve started planning for the next major update that will meet users’ growing demands, but will require some breaking changes to do so. As of right now, the high points include:

Major changes

  • Plugin chaining. Right now plugins are completely isolated from one another (except for CSS + Sass, which still have lots of rough edges, and whose current interop isn’t a pattern that should be repeated). This has been workable with official plugins, but imposes restrictions on how custom plugins are made.

    I’m currently working on a draft for the Plugin 2.0 syntax, which is basically “the same, but more.” It will give plugins (many) more hooks than just the one build() hook so they can work off one another, and you can transform tokens in multiple passes before preparing them for an output format. And while it’s still a little early for feedback, I’ll open up RFCs in the coming weeks when I’ve proven the changes will simplify current plugins and allow for more complex chaining and better sharing of logic between plugins. The API will still be primarily Rollup/Vite plugin-inspired, but will introduce new concepts where it makes sense (since tokens are fundamentally different than web bundlers). Ideally, this means if you have a custom plugin for 1.x, migrating to 2.x won’t be too bad. But internally, the execution of plugins will differ quite a bit and unlock some pretty cool potential.

  • Support for DTCG 1.0. DTCG 1.0 (stable) is chugging along! The community group is going through the process now of finalizing decisions and fixing some long-requested issues with the working draft spec. TBD if this will be officially stamped and sealed by end of 2024, but I can say that progress is happening.

    • Status: ⌛ Slowly but surely
  • AST-aware errors. Currently, Cobalt throws pretty vague errors when reading tokens.json because it doesn’t keep track of the line it’s on. Likewise for YAML and JSON parsing errors. 2.0 will run error-checking earlier in the parse phase, where it can helpfully print out the correct line in case of a syntax (or schema) error.

    • Status: ✅ JSON (using Momoa) / ✅ YAML

Minor changes

  • Building moved to core. Currently the @cobalt-ui/core package isn’t very useful; it can only validate & normalize the schema but can’t do any meaningful work with the plugins. It wasn’t an intentional design decision to keep most of the building within the CLI package; it was just expedient to do so originally. Moving it to core unblocks people who want to run post-build actions in Node.js without having to read/write from disk (which means it could even be used in APIs, and in the browser).

    • Status: ✅
  • Parsed Tokens object instead of an array. If you’ve built your own plugin in 1.0, you’d know that tokens.json is passed in as a flat array. This will be changed to be a shallow object (with . in keys).

    The original assumption was “since plugins will always be iterating over all tokens anyway, let’s make it simpler,” but that has proven false over time. There are many times when plugins need to grab individual tokens, and tokens.find(…) is not only verbose but slow (comparatively). Objects are closer to the original tokens.json, which makes things simpler to work with. The parsed tokens object will still be shallow, because it is still more time-consuming/more complex to do deep AST traversal than running over a loop once.

    • Status: ✅
  • Getting rid of internal weirdness. There are artifacts internally like metadata which don’t have clear purpose other than “IDK here’s some junk we may need later maybe” (spoiler alert: we didn’t).

    • Status: ✅

Staying the same (no changes)

  • Performance is (still) a priority. I am a huge fan of wasm and languages like Rust, but the nature of working with design tokens is still well within the realm of what Node.js does well all on its own. Adding additional languages on top of Node.js comes with drawbacks including increased difficulty of contributions, more complex debugging, fewer releases, and more difficult plugin authoring. I’m always conscious of how fast (or slow) Cobalt is, but as of now it’s very fast and lightweight, wasm wouldn’t solve any problems, and 2.0 won’t change that.

  • Ease of creating plugins is (still) a priority. Above all, it should be great DX to use Cobalt with existing plugins, and shouldn’t be much harder to write your own. Rollup/Vite continue to be sources of inspiration of timeless APIs that are the perfect blend of simplicity where needed, and complexity where required.

  • No new token types (for now). “Boo!”—I know. This is actually good news, in a sense. If DTCG 1.0 releases this year, it will be a big deal! Figma, Adobe, PenPot, and more have eyes on the DTCG spec, and plan to implement it in their products as soon as possible. Cobalt exists first and foremost to implement that spec as-designed, which maximizes the number of ways you can use Cobalt and its plugins. It will be better for everyone to not have yet another competing standard that forks the spec just to add additional token types.

  • (Still) independent of Style Dictionary. Since Cobalt’s release, Style Dictionary has announced an exciting new v4 with support for DTCG, which I’m looking forward to! Style Dictionary was foundational for so much advancement of design tokens (even DTCG) and I’m excited to see that project continue.

    As a project, Cobalt isn’t seeking to be a 1:1 replacement for SD. Cobalt seeks to provide tooling for the DTCG, and also explore working with design tokens with a plugin-centric API rather than a looser, config-heavy “Gulp-like” one. Ultimately it’s about giving developers more options in tooling to meet different needs, and I love when Style Dictionary works and works well for people. So all that said, Cobalt as a project will continue to explore an API that allows for easy, zero-config usage, but without restricting powerful customizations. Independently of what Style Dictionary is doing. And I hope that both Cobalt and Style Dictionary continue to both grow and develop, and continue to meet developers’ differing needs well!

Note: this is a living document; expect edits (and even some decision reversals) as plans develop and mature.

Release date: Late 2024, with RFCs coming Mar/Apr

To recap, this is mostly a placeholder announcement to check back in at a future date for RFCs and testable beta versions of Cobalt 2.0. While a stable version won’t release before DTCG 1.0 is closer, look out for both RFCs and testable beta versions very soon (in the coming weeks).

So all that to say, is there anything you’d like to see in Cobalt 2.0? At this early stage, any and all ideas are welcome (keeping in mind a Plugin 2.0 API will get an RFC soon)! Is there more Cobalt could do out-of-the-box? Any work that could be moved out of your plugin? Any additional integrations you’d like to see? Leave a comment!

Thanks for reading 🙏

@drwpow drwpow added enhancement New feature or request help wanted Extra attention is needed question Further information is requested labels Feb 26, 2024
@drwpow drwpow pinned this issue Feb 26, 2024
@drwpow
Copy link
Collaborator Author

drwpow commented Feb 27, 2024

😄 Fitting that this is 201

@torstendaeges
Copy link

Sounds great, really looking forward to this! :)

@drwpow
Copy link
Collaborator Author

drwpow commented Mar 16, 2024

Had a bit of a breakthrough this week in what’s probably the most exciting development since this library started: token linting. As a PoC I’ve shipped an a11y plugin that can perform contrast checks on your tokens automatically (WCAG 2 and APCA). And under-the-hood is a whole new linting setup that lets Cobalt plugins register linters that users can configure their own rules on, similar to ESLint.

This is huge because Figma plugins exist, but are manual. And designers shouldn’t perform QA (nor does the “source of truth” usually exist in Figma anyway). a11y tests also exist of course, but are often very slow and expensive because without a token pipeline you have to run full E2E tests with browsers (and still miss some things). But with token linting, the tests are fast, cheap, accurate, and surface in the part of the chain where they can be fixed: design ops. See the RFC for more info and to give feedback!

I’m excited for all the possibilities this opens, especially with the new improvements coming in 2.0. And would love to hear ideas for other linting checks we could add to test the concept further!

@dzonatan
Copy link

And would love to hear ideas for other linting checks we could add to test the concept further!

not related to a11y but it would be nice to check if there are no duplicate token names, e.g.:

      "blue": {
        "0": { "$value": "#ddf4ff" },
        "1": { "$value": "#b6e3ff" },
        "2": { "$value": "#80ccff" },
        "3": { "$value": "#54aeff" },
        "4": { "$value": "#218bff" }, // <--
        "4": { "$value": "#0969da" }, // <--
        "5": { "$value": "#0969da" },
        "6": { "$value": "#0550ae" },
        "7": { "$value": "#033d8b" },
        "8": { "$value": "#0a3069" },
        "9": { "$value": "#002155" }
      }

now last value wins. maybe this could be even checked in compile time.
IDEs usually flag these duplicate properties but this could happen by other means like wrong git conflict resolution.

also, just a thought, maybe checking duplicate token values within the same group would also be helpful:

      "blue": {
        "0": { "$value": "#ddf4ff" },
        "1": { "$value": "#b6e3ff" },
        "2": { "$value": "#80ccff" },
        "3": { "$value": "#54aeff" },
        "4": { "$value": "#218bff" }, // <--
        "5": { "$value": "#218bff" }, // <--
        "6": { "$value": "#0550ae" },
        "7": { "$value": "#033d8b" },
        "8": { "$value": "#0a3069" },
        "9": { "$value": "#002155" }
      }

@drwpow
Copy link
Collaborator Author

drwpow commented Mar 18, 2024

Yes @dzonatan that’s exactly what I’m talking about! Duplicate values could be done today. Duplicate keys (IDs) would have to wait for 2.0 as that requires AST awareness (parser rebuild). But both are good examples of “core” lint rules that I think should just work out-of-the-box (maybe the lint rules are opt-in, but no plugins to install)

@drwpow
Copy link
Collaborator Author

drwpow commented Mar 30, 2024

@dzonatan Thanks to your suggestion, I just shipped the duplicate-values lint rule (along with some others) that lets you catch duplicate values anywhere in your tokens.json file. Please give it a try and let me know if you encounter any errors 🙏

duplicate keys turned out to be pretty tricky! Because the JSON spec does allow for duplicate keys (it just takes the last one silently), fixing that requires a implementing a custom JSON parser so that may take a while 😅

@drwpow
Copy link
Collaborator Author

drwpow commented Apr 1, 2024

💠 Announcing … Terrazzo!

Figured I’d let the cat out of the bag with future plans for this library in the 2.0 release. I won’t give all the details here, but just some high points:

Cobalt will be renamed to Terrazzo!

Cobalt was always a placeholder name. I was always more focused on the actual tooling for DTCG, and never felt truly attached to the name. “Cobalt” is a common name that competes with many things, both in programming/design and beyond. I never felt it captured the nature of tokens: these little beautiful, colorful things that come together to form this wonderfully-intricate and unique pattern…

…kinda like terrazzo!

The name also highlights an expansion in the maintainers. For a while now, Cobalt has been a solo side-project. But this year I’ve roped in a good friend and incredibly-talented designer, @ntassone, to make this 100× better than it ever would be with just myself. Together, we’ve realized a lot of pieces were missing in the story of design tokens:

  • Visual Tokens Editor: edit tokens with an OSS tool (kinda like Storybook but for tokens)
  • Better design tools: I’ve been inspired by a lot of the work that Evil Martians have done such as oklch.com, and wanted to make my own
  • Token linting: We built it this month, but there are so many unexplored ideas here, still
  • A bigger ecosystem: I’ve been working on Cobalt solo for a few years now as a passion project, and I want to do things that incorporate more people (like @ntassone)!

So all that considered, we wanted a bigger, better Terrazzo namespace to contain all these ideas and experiments we’ve been working on for a while behind-the-scenes. And also open the doors to more people getting involved.

Is this a company?

No. It’s still an 100% open-source project @ntassone and I are working on in our free time. It’d be neat to find a way to get more funding for this somehow! But only time will tell.

So is Cobalt going away?

Nope! Cobalt v2 == Terrazzo CLI v1. 100% of Cobalt’s direction, vision, and philosophy won’t change. Terrazzo will just be a project that’s a suite of token tools in addition to just a CLI.

Why announce it here? … In this thread?

The Terrazzo nameswap was something we had been planning before even announcing 2.0. But @ntassone and I had been mulling over what the actual scope was until pretty recently, and how Terrazzo related to Cobalt. After deciding on a scope, and deciding Terrazzo was the same as Cobalt, we knew the actual swapover would be a little clumsy, and there wouldn’t be some seamless overnight launch. Over the next few months, you’ll start seeing the name “Terrazzo” here and there in the project. And one (undisclosed) day in the future, this repo will suddenly move to the Terrazzo GitHub org. And we wanted people to know it’s not changing hands (just adding some!).

I actually don’t even like talking about things before I do them; doing is more fun! But the people reading this thread would start to notice the changes before anyone else, so this seems like the most effective way to announce it 🙂.

And as always, always open to any questions people have! 🙇

@drwpow
Copy link
Collaborator Author

drwpow commented Apr 9, 2024

Lil sneak peak: the beta version is a little further away than planned (hoping to get a version published in a couple weeks, but we’ll see), but here’s a sneak peak: full AST support for tokens.json! 😎

CleanShot 2024-04-09 at 09 53 07@2x

It’s not just showing the specific line that erred in feedback (though it does enable that). It also exposes the JSON AST to plugins as well so you’ll have access to the original tokens.json file as-authored (if you need it).

This will also enable line-specific lint messages as well! Excited for this update!

@drwpow
Copy link
Collaborator Author

drwpow commented May 3, 2024

Lil update: the 2.0 version is very, very alpha, but those interested can take a look at the new 2.0 docs here regarding the plugin changes: https://terrazzo.app. Design credit for branding and docs styling goes to @ntassone; I couldn’t have done this without him!

You can also kick the tires on @terrazzo/cli and @terrazzo/plugin-css which are available on npm. Work the same way, but with a terrazzo.config.js file instead of tokens.config.js.

With the core rewrite mostly done, hoping to have the rest of the plugins upgraded to 2.0 in the next month, finish styling / writing docs, and hopefully we’ll have some release candidates ready in the coming weeks.

And as always, feedback is always welcome! (particularly about the plugin API enhancements)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants