Latest update: Cosmos 4.8 — the version that keeps on giving
Install react-cosmos@next
to get started.
The example package is a useful complement to this guide.
No config is required to start. If you have custom needs or would like to convert a Cosmos Classic config, here's what you need to know.
The Cosmos Next config is a JSON file, so it can only host serializable values. This design decision is meant to discourage complex configuration, make it easy to embed config options into the UI, and enable visual config management in the future.
By default, Cosmos reads cosmos.config.json
from your root directory. You can pass a --config
CLI arg for a custom config path.
Most Cosmos Classic config options are still supported in the new JSON format. Let me know if you need old config options that no longer work.
Configuring webpack is the least romantic aspect of the Cosmos setup. Luckily, you only do it once. Depending on your setup, one of the following options will work for you.
In many cases Cosmos manages to get webpack working without human intervention. Try running Cosmos as is first.
Probably the most common scenario. Most of us end up with a hairy webpack config sooner or later. Use the webpack.configPath
setting to point to an existing webpack config.
You can also point to a module inside a dependency, like in the following Create React App example.
{
"webpack": {
"configPath": "react-scripts/config/webpack.config"
}
}
Overriding the webpack config gives you complete control. Use the webpack.overridePath
setting to point to a module that customizes the webpack config used by Cosmos.
{
"webpack": {
"overridePath": "./webpack.override.js"
}
}
The override function receives a base webpack config — the default one generated by Cosmos or a custom one loaded from webpack.configPath
. Extend the input config and return the result.
// webpack.override.js
module.exports = (webpackConfig, env) => {
return { ...webpackConfig /* do your thing */ };
};
Cosmos Next introduces a more natural format for component fixtures: React elements and React functions.
Some advantages compared to the old format in Cosmos Classic:
- Fixtures are no longer bound to a single component
- Adding one or more component wrappers per fixture is easy
- Fixtures can be copy pasted inside the project source code
- Props are easier to type-check
- Writing fixtures doesn't feel like writing code for Cosmos
The new fixtures formats also come with a minor drawback: React
must be imported in every fixture file.
Think of Element fixtures as the return value of a render function, or the first argument to
React.render
.
// __fixtures__/disabled.js
export default <Button disabled>Click me</Button>;
Function fixtures are like a component with no props. They enable using Hooks inside fixtures, which is powerful for simulating state with stateless components.
// CounterButton.fixture.js
export default () => {
const [count, setCount] = React.useState(0);
return <CounterButton count={count} increment={() => setCount(count + 1)} />;
};
A fixture file can also export multiple fixtures if the default export is an object.
// buttons.fixture.js
export default {
primary: <PrimaryButton>Click me</PrimaryButton>,
primaryDisabled: <PrimaryButton disabled>Click me</PrimaryButton>,
secondary: <SecondaryButton>Click me</SecondaryButton>,
secondaryDisabled: <SecondaryButton disabled>Click me</SecondaryButton>
};
The object property names will show up as fixture names in the Cosmos UI.
See this comment for the reasoning behind this solution (vs named exports).
Two options:
- End fixture file names with
.fixture.{js,jsx,ts,tsx}
- Put fixture files inside
__fixtures__
Examples:
blankState.fixture.js
__fixtures__/blankState.js
File name conventions can be configured using the
fixturesDir
andfixtureFileSuffix
options.
Wrapping components inside fixtures is now easy, but can become repetitive. Decorators can be used to apply one or more component wrappers to a group of fixtures automatically.
A cosmos.decorator
file looks like this:
// cosmos.decorator.js
export default ({ children }) => <Provider store={store}>{children}</Provider>;
A decorator file only applies to fixture files that are contained in the decorator file's directory. Multiple decorator files can be composed, in the order of their position in the file system hierarchy (from outer to inner).
Check out react-cosmos-redux to see what a Cosmos Next decorator looks like. It works with the latest react-redux
version and it's written in Hooks 💃.
A main feature of the Cosmos Next redesign is the brand-new UI plugin architecture. While the new UI is created 100% from plugins, the plugin API is not yet documented nor made accessible. It will take a few big steps to get there, but this is the future.
While we get feedback for the new JSX fixtures and decorators, I will continue to add feature parity with the old Cosmos UI and gradually release the powerful plugin API for mass consumption. Exciting things ahead!
responsivePreview
is a plugin included by default, and you can customize it through the Cosmos config.
{
"ui": {
"responsivePreview": {
"devices": [
{ "label": "iPhone 5", "width": 320, "height": 568 },
{ "label": "iPhone 6", "width": 375, "height": 667 },
{ "label": "iPhone 6 Plus", "width": 414, "height": 736 },
{ "label": "Medium", "width": 1024, "height": 768 },
{ "label": "Large", "width": 1440, "height": 900 },
{ "label": "1080p", "width": 1920, "height": 1080 }
]
}
}
}
Cosmos Classic isn't going anywhere. First, it will take months before a release candidate for v5 (Cosmos Next) is ready. Second, the classic packages have been moved to a dedicated repo, which means we can continue to maintain Cosmos Classic or even run it alongside Cosmos Next in the same project (during the migration period).
Thanks for your help in shaping the future of React Cosmos! 🙏
For feedback create a GitHub issue or go on Slack.