Storybook: UI component explorer for front end developers(storybook.js.org) |
Storybook: UI component explorer for front end developers(storybook.js.org) |
Consider just rolling your own component showcase. You can do it in a day and probably get a much cleaner and more straightforward static site out - all you really need is a sidebar and then display areas hooked up to buttons. That's it. Storybook is just a heavy, complicated, awkward set of abstraction layers over that very simple core experience.
Oh, and that “S” thing. Yeah, I hit that. Grr.
Nice "isolation" they have when they bundle in whole corejs into component view.
My component was parsing a lot of dates from RFC3339 string via `new Date` and it was mind-blowlingly slow. I opened dev tools and was greeted with javascript re-implemenation of the Date constructor in all glory.
Suffice to say that I had zero intentions to ship that into production bundle. Thanks Storybook, isolated playground indeed.
Writing documentation for the components is a weird mix of JSX, interpolated strings, and markdown. Often overlapping, confusing, and conflicting ways of doing the same thing.
Change anything about your webpack config? Good luck. Updating SB itself is also always a complete pain in the ass.
Worst of all, there are conflicts between its internal code and your app code. "isolated" is a lie, your components are webpacked along with theirs so if you use Emotion for styling for instance, suddenly you have a conflict in the style context.
Building a custom solution can be worth it depending on how many features you use.
The idea behind Storybook is great, but it’s gotten slower and heavier over the years and it seems like the project has lost direction. Is it a component sandbox or a documentation website? IMO, it does neither of them well anymore. The UI is hard to customize, the shortcuts are annoying (pressing S while focused in an input toggles the sidebar, for example), and it takes forever to install and launch.
I moved on a few years ago and haven’t missed it.
We still use it, because management doesn’t like the idea of how much time we’ve already sunk into it. Storybook is a nightmare to maintain and train devs on.
It gets more complicated when you want to let people play with the component's props/parameters from within the GUI. I hand-rolled one of these once and was able to use a library that scraped prop info from our React PropTypes automatically and put it into a JSON file, but it was fiddly and eventually broke when we started using TypeScript. I don't know if something better exists now (or how Storybook solves this), but it's a hard problem. And it's not just about gathering metadata: you have to dynamically set aside a piece of state for each prop that hooks in accordingly. Sometimes, like with value/onChange, you need to hook two different props together into the same piece of state. Etc.
I suppose you could just hand-code all the controls for each component, but at that point it seems like it would be more trouble than it's worth (especially the ongoing maintenance burden every time one of the base components changes)
Actually storybook has become sort of a litmus test: If you need to hack storybook to death to make your fancy thing work, then it means that you will have trouble with other tools anyway (Jest, Cypress, some CI tool or some Browsers), so maybe reconsider it first.
So your mileage will vary. But on fresh modern project my advice would be: go for it (and use Chromatic as well in your CI, it is super cool!). If you have to use fancy stuff that make storybook too complicated then drop it.
It’s easy to drop, but not easy to insert in an existing project. But for me the storybook / chromatic Combo has a 10x ROI on a project in 2021.
For frameworks with complex webpacks (e.g. gatsby) it's actually really hard to integrate well, particularly when you don't really want to get that deep into webpack itself.
It’s useful also to keep semi static mockups when you do revisions on a homepage for example (as the html/css guy) so you can preview something with the team.
And nowadays you have simple Markdown + Vue plugins for eg. Vite, so you could even write your styleguide / demo as .md files.
Isolated components that can be tested under different scenarios is a great idea, but I've found it uncovered almost no bugs and served almost exclusively as a showcase.
Since Timvir is basically just a component library and not a build tool on its own, integrating it is quite easy, and won't break whenever you upgrade Next.js, Webpack etc. That was one my my main motivations: tools that come with their own build system are hard to make, and even harder to make reliable. You are buying convenience in the short term, but getting pain in the long term.
But it usually only went as far as having the designers follow it in Sketch, Figma or whatever, and the devs separately implementing the components themselves.
What is the (supposed) added value of something like Storybook over this?
Yes. While I otherwise like Storybook, the addition of docs along side canvas is not clear what the purpose is. Incremental way to introduce a new default? Very confusing to have both tabs available at same time.
In fact what we end up doing with Storybook is that we create the "stories" (literally .stories.ts files) that renders each component with a specific permutation of props. However this is pretty much a copy of the .test.ts file we write for the component itself - so many times it's literally doing pretty much the same stuff.
I find it so weird that in 2021 we don't have a way to just render our test files (which essentially is using some server-side dom abstraction) also to a browser so we can view the component and develop against it.
Then we wouldn't need storybook or story files that describe how a component is rendered - that's the test file responsibility.
https://github.com/storybookjs/storybook/tree/main/addons/st...
I can write automated tests to verify that a component in a relevant context still functions, and can have a check at PR time to verify that the UI hasn't changed unexpectedly.
Running all tests in Cypress would result in slow CIs.
Tough luck - you'll need to implement it for both the app you're building and Storybook. And sometimes implementing it in the app itself is the _easy_ part. Nevertheless, I feel like it does improve the dev experience and intend to keep using it. You just need to know when to cut your losses and not use it for more complex use-cases.
I love the idea of SB but haven’t come across a project where it actually works with the components.
As a bonus, the stories that get created live in your codebase and can be integrated into several different types of testing - jest test suites, visual regression testing, and puppeteer / Selenium.
There's certainly an overhead for mocking data properly, but I tend to see that as part of the general challenge of testing frontend / JS code.
For complex data from the API I have actually added tooling very similar to VCR that allows me to record API req/responses from the backend into "cassette" JSON files that can be "loaded" on a per-story basis. Don't use it for everything, but it has worked out very well where it has been used.
I also think that building a bespoke environment for building components in isolation isn't that hard and is probably worth doing if the company is thinking long term. I'll certainly be doing that in the future.
So I checked it out and it’s not clear to me how if it all it supports different frameworks. All the examples seem to be for handlebars based components not actual components in the JS framework sense of the word.
https://github.com/frctl/fractal/blob/main/package.json
Is there a similar project without, e.g. the React dependencies for projects that might not include React?
I hope nowadays it’s more stable. Personally I’ve ended up rolling my own and it works as a charm, integrated with unit tests
I agree it's still heavy and when it breaks may god help you. But when it works, it's pretty nice. I am really happy with how clean stories files can be now, for example: https://github.com/city41/smaghetti/blob/main/src/components...
You end up developing the components in a separate repo, and in your main app repo you install each component as dedicated npm package. Those who get excited by `separation of concerns` pattern should find this a real joy.
I like to be able to modify my component and immediately (one hot reload) be able to modify a site of use of this component one second later. Having 1+min of npm publish and npm install get in the way is not what I want.
But I can understand the utility for some different use cases.
That said, I've really wanted a good alternative for React Native that's similar. Storybook ostensibly works there, but it's more than a little clunky.
Also are you able to leverage it for automation test? I.e. if you have a photo gallery...have a state where it has 0 photos, 1, 2.. and have some UI automation test (i.e. Selenium) run against it?
If not do you have any recommendations for something like this kind of use case?
And yes, we use Chromatic (their hosted service) and it’s been hugely beneficial, I would say a 10x ROI. Super useful for visual regression testing, sharing with non technical people in the org, etc...)
My recommendation in this field is Storybook. It’s the best tool for this use case. We also use Cypress for integration tests and heat for unit tests.
I tried looking up "Heat" but was not able to find a framework/util. Could you send me the link please?
It looks like the testing feature of Chromatic is to take screenshots of the deployed component and visually compare them? So there's literally no code writing if comparing one commit to the next.
Will use it for building components of any complexity and size under "screen" leaving just the "last mile" to work out in the legacy app. Have it configured so the API can be hit and/or pre-recorded API calls can be used.
It has made cross-browser testing and fixes(looking at you Safari) quite quick. Leaned on it for large CSS/SCSS refactors and style updates.
Could something like this be written from scratch? Sure, but why? It's a set of conventions already in place and documented. Setting it up was a breeze and creating a "story" can be just about as simple or complicated as you want.
There's lots of reasons: it is simple enough that it can be done in an afternoon. It is a great learning exercise, especially for junior devs. It has hard dependencies on React, Webpack, Babel, Reach Router, PostCSS that can cause you project to break if you're not careful, not to mention the bloat. If you use Vue, Typescript or other bundler you have a lot of redundancy now, and possibly some quirks due to incompatibilities between bundlers. Also there's UI/UX quirks. And it's harder to customise than a plain page.
I'm all for reusing other projects and saving time, but the automatic reflex we have of automatically adding dependencies without considering the downsides becomes very problematic in non-trivial projects.
Boy howdy. Of course, every NIH project that turns into a huge wasted time sink has a rationalization chock-a-block with reasons.
It depends. YMMV. etc.
Extra work for no benefit, broken builds, type and lint ignores everywhere, demos always out of date or incomplete.
If your designers are skilled and organized, you don't need this. "But my team doesn't have skilled or organized designers!" ... well then you probably have bigger problems, messing with Storybook is the last thing you want.
Why would design your components in isolation? Do they never interact with each other? Appear next to each other on a page? Participate in a layout?
This is my main gripe with Storybook in particular and any design system and design system tool in general: they never consider how components work together and force into a mindset of just documenting separate components complete isolation.
Storybook gives you the framework to run them. Add something like cypress on top and you have the whole testing loop.
Making and updating the components in isolation reduces how much you need to reason about when building highly composable components.
The higher up you go (ie more composition) the less you can do in isolation.
But this is only building, you should design with as full an understanding of the rest of your components. Behaviours need to match, style needs to be consistent.
You don’t build a whole program at once, in the same way you can’t build a whole UI at once. At some point, you focus in on one area.
This because exponentially helpful when you team grows to a size larger than one.
How do you know they are composable if you make and update them in isolation?
When you are building an app bottom up, you will be working on components “in isolation” 100% of the time all the way up. Integration between components is just part of the behavior of a component higher in the hierarchy.
You can make stories of larger components assembling smaller components, entire pages, and even your entire app!
It’s been very valuable for my teams, especially coupled with Chromatic.
What? When you're building an app, you will always have components interacting with each other and being used with each other.
Advantages
- Testing components in isolation forces some good practices and allows to keep the codebase in check by encouraging good practices (limited coupling of unrelated parts of the codebase
- It’s super productive because it is both a form of unit tests, useful during development of UX in « TDD mode », and a very good documentation of your UI components. It greatly reduces the effort needed for both these aspects.
- For DX, the hot reload is generally faster in storybook than in the App (except if you use vite/snowpack in your app, so far..) because reloading a single component is faster than reloading the whole app and its state. In a large CRA our hot reload could sometimes take up 1min in complex cases, while storybook was taking 3s.
- Coupled with Chromatic (their hosted platform) and its GitHub integration it makes QA and visual regression testing a joy, 10x faster than alternatives, I really recommend that.
- It allows to share/iterate easily your ongoing developments with non-tech people in your organisation at early stage. A very good bridge between Figma and the final UI. A good support during Daily meetings about UI, just share the deployed story url to ask for feedback.
Drawbacks
- It has its own Webpack config. So if you have a custom Webpack config in your app (don’t do that anyway, unless absolutely necessary) then be prepared to duplicate the customizations in your storybook config
- Global React Contexts needs to be duplicated in your storybook config and, if necessary, configured for individual stories. For example if your signup button changes based on an Auth status stored in a global context, then you will have to use Story.parameters to customize the content of the Auth context.
- We had a couple instances where storybook was the limiting factor for us to embrace some new/fancy tech, like yarn v2 or service worker. However maybe that’s a good litmus test: things that storybook support are state of the art JS and generally safe to use. Things that storybook does not support out of the box will cause you problems with other tools anyway: if it’s not storybook, some other tool like Cypress, Jest, Next, or some browsers will cause you trouble with your “shiny new tech”
- It can be slow to startup. We had a storybook with 300+ complex stories and it took 5min to startup and 10min to build in the CI
- It had some API changes/ migration pains a couple years back. However I think the new API is very good and will last a long time so this is behind.
Overall I definitely advocate to use storybook, especially with Chromatic, the ROI is 10x. If you find yourself limited by it in 2021 despite configuring it, maybe question your own tech stack.
Don’t try to implement your own storybook copycat (we had a colleague develop an alternative https://github.com/remorses/vitro , but i think it was not worth the effort)
If you want to see a state of the art monorepo in NextJS that uses storybook extensively with some customizations, check https://github.com/Labelflow/labelflow/
A component system is very useful though. Wish something simpler was available.
Have you tried it recently ? It’s pretty simple to add decorators and data loaders if you need customization.
It is not zero-cost though of course but I find the ROI to be closer to 10x than to 0.
In my experience the react crowd is more likely to use other people's components instead of rolling their own, even when it barely makes sense or is counter productive
As if components existed in a void.
And yes you are right about Chromatic. It informs you directly in GitHub PRs about the number of stories that changed, visually or at the dom level. And has a nice UI to review changes visually in a click.
If you think I'm taking a side by merely pointing out something has downsides: you're projecting. Neither reusing nor building from scratch should be automatic decisions taken without consideration.
Tbh without the ability to play with props I wouldn't even bother with a storybook-like interface. As you say, they probably have the code (and all its comments) in front of them, so what's the point of pretty documentation at that point?
The only benefits for the knobs I see is to provide a nice interface for the designers to scrutinize the system on an atomic level. However I am not a designer so I don’t know how valuable it is for them to do that through story book over exploring the actual app or a custom showcase. And if the benefits to the designers are only marginal, you have to ask if it is worth it for devs to maintain the storybook interface.
But even if we had, we might not have discovered things like "oh, if you have the modal set to show a close button in the corner and also give it a really long title and make the window narrow then the button gets awkwardly pushed to the next line". The kind of stuff that mockups often don't cover, but real-world users might encounter some day.
E.g, the interaction between the submit button and the email input box is just the behavior of the whole form component. In react at least, your app is a component, so literally all the logic of your app is in a component in the end. And you can rest this component in storybook. So really there is no limit to what you can test in storybook in that sense.
It's not "just another component up in the hierarchy". If your components are truly composable, you don't need to create another "component" to be able to use them. But you do need to show how they can be used together.
> And you can rest this component in storybook. So really there is no limit to what you can test in storybook in that sense.
And yet, I keep seeing "components in isolation" and all examples (and all storybooks I've seen) have little to no examples of how these isolated components are used together.
And storybook allows to show the code of stories, which is equivalent to a « getting started » or usage example for each of these components in docs. Except that it is guaranteed to be evergreen, since if these examples break, my CI wouldn’t pass.
Labelflow is a public repo I manage with storybooks like that. We use Chromatic with storybook in there. Search for folders named « __stories__ » for stories at all level of the hierarchy. https://github.com/labelflow/labelflow