Installations
npm install react-cosmos-apollo-proxy
Developer
react-cosmos
Developer Guide
Module System
CommonJS
Min. Node Version
Typescript Support
No
Node Version
10.15.0
NPM Version
lerna/3.10.8/node@v10.15.0+x64 (darwin)
Statistics
4 Stars
1,507 Commits
3 Forks
3 Watching
1 Branches
68 Contributors
Updated on 27 Sept 2024
Languages
JavaScript (69.32%)
CSS (29.88%)
HTML (0.8%)
Total Downloads
Cumulative downloads
Total Downloads
252,686
Last day
-45.9%
20
Compared to previous day
Last week
17.6%
187
Compared to previous week
Last month
24.4%
667
Compared to previous month
Last year
-50.4%
10,908
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
React Cosmos ✭ Dev tool for creating reusable React components
⚠️ This repository hosts Cosmos Classic, which has entered maintenance mode. You can continue to use Cosmos Classic indefinitely. If you want to get on board with a newer platform, however, or if you're just getting started, check out Cosmos Next.
Cosmos scans your project for components and enables you to:
- Render components under any combination of props, context and state
- Mock every external dependency (eg. API responses, localStorage, etc)
- See app state evolve in real-time while interacting with running instances
Working with Cosmos improves component design because it surfaces dependencies. Cosmos forces us to define sane component inputs, making our UIs predictable and easier to debug down the road.
Read the story of React Cosmos: Fighting for Component Independence
Why Cosmos?
Many other component explorers emerged in the past years. Storybook and React Styleguidist are good examples, but you can find an extensive list of options here. Check how much each tool matches your needs to decide which is best for you.
Cosmos is a dev tool first, made to improve all components, big and small, not just the stateless UI bits. The fixture and proxy architecture doubles as an automated testing utility, providing a complete solution for developing robust and reusable components. Cosmos also makes it easy to create a living style guide, but it's a secondary goal and you might get more value from alternatives if this is your chief concern.
Usage
Requirements:
- React >=0.14.9
- webpack or Browserify (or roll your own integration)
- Fixtures (you'll create them after getting started)
React Cosmos works best with webpack. Making it work with other bundlers takes extra work, but both a Browserify example and a Parcel example are available.
Jump to:
- Getting started
- Fixtures
- Proxies
- Integration with popular tools
- Config
- Exporting
- Headless testing
- Beta: React Native
- Flow integration
Have a question or idea to share? See you on Slack.
Getting started
Install via npm
1npm install --save-dev react-cosmos-classic
or Yarn
1yarn add --dev react-cosmos-classic
Add package.json scripts
1"scripts": { 2+ "cosmos": "cosmos-classic", 3+ "cosmos:export": "cosmos-classic-export" 4}
Run npm run cosmos
or yarn cosmos
and go to localhost:8989 🎉
If you rely on the default webpack config, make sure to install the Babel and webpack plugins yourself. Depending on your needs, you'll probably want
@babel/core @babel/preset-env @babel/preset-react babel-loader style-loader css-loader html-webpack-plugin
. Finally, add.babelrc
to your project root.{ "presets": ["@babel/env", "@babel/react"] }
NOTE: The above
.babelrc
and@babel/*
namespaced packages only apply to Babel 7.x and above.
Next steps
If everything's working
If something's wrong
- Extend existing webpack config
- See popular integrations (e.g. CRA or Next.js)
- Extend your config
- Be kind and report what went wrong
Fixtures
Old fixtures need to be adjusted to work with Cosmos v3. Check out this guide for upgrading.
What's a fixture?
A fixture is a JS object used to mock component input and external dependencies. The input can be props, children, state and context. With the help of proxies, fixtures can mock anything else a component depends on, from API responses to localStorage.
1import Input from './Input'; 2 3export default { 4 component: Input, 5 props: { 6 value: 'Lorem ipsum', 7 disabled: true, 8 onChange: value => console.log(`Select: ${value}`) 9 } 10};
Check out this quick hack for getting started with fixtures.
Where to put fixtures?
Cosmos looks for *.fixture.js
named files and files inside __fixtures__
dirs by default. See custom fixture paths for further customization.
It is also possible to export an array of fixtures from a single file. You may want to define the fixture name and namespace in this case.
1export default [ 2 { 3 component: Input, 4 name: 'disabled', 5 props: { 6 disabled: true 7 } 8 }, 9 { 10 component: Input, 11 name: 'enabled', 12 props: { 13 disabled: false 14 } 15 } 16];
Props
Mocking props is the most basic thing a fixture can do.
1export default { 2 component: Auth, 3 props: { 4 loggedIn: true, 5 user: { 6 name: 'Dan the Man' 7 } 8 } 9};
Children
Composition is the name of the game and many React components expect children. You can specify your children just like you would any other prop:
1// React needs to be in scope for JSX to work 2import React from 'react'; 3 4export default { 5 component: Text, 6 props: { 7 someProp: true, 8 children: ( 9 <div> 10 <p>Fixture ain't afraid of JSX</p> 11 <p>Fixture ain't afraid of nothin!</p> 12 </div> 13 ) 14 } 15};
State
Mocking state is where things get interesting. Component state is private IRL, but Cosmos allows us to inject it and simulate all the various states a component can find itself in.
1export default { 2 component: SearchBox, 3 state: { 4 searchQuery: 'Who let the dogs out?' 5 } 6};
Wrapper component
You may identify a component directly, or provide a function. This allows for quick wrapping of components. If you find yourself doing this often with the same component, it might be time to try proxies.
1export default { 2 component: props => ( 3 <Well> 4 <SearchBox {...props, placeholder={'What are you looking for?'}} /> 5 </Well> 6 ), 7 props: { 8 value: 'apples' 9 } 10};
You may also want to specify a display name for this component. To do so, you can a separate variable for the wrapper component and assign it a displayName
:
1const WrapperComponent = props => ( 2 <Well> 3 <SearchBox {...props, placeholder={'What are you looking for?'}} /> 4 </Well> 5); 6 7// The fixture will be shown in the tree as SearchBox 8WrapperComponent.displayName = "SearchBox"; 9 10// separating names with a / will make the fixture SearchBox 11// appear in a nested folder called "styleguide". 12// WrapperComponent.displayName = "styleguide/SearchBox"; 13 14export default { 15 component: WrapperComponent, 16 props: { 17 value: 'apples' 18 } 19};
Init hook
This is an advanced feature and should only be used when a desired state can't be reproduced via proxies.
1export default { 2 component: Dashboard, 3 async init({ compRef }) { 4 // With great power comes great ref-sponsibility... 5 } 6};
Fixture name and namespace
The fixture name and namespace are detected automatically from the file name and file path respectively, but they can be overridden with custom values.
1export default { 2 component: SearchBox, 3 name: 'dog search', 4 namespace: 'dashboard/pets' 5};
Proxies
What's a proxy?
Proxies are Cosmos plugins, allowing fixtures to go beyond mocking props and state.
We've seen component = f(props, state)
a hundred times–the seductive promise of React and libs alike. In reality, however, it's more like component = f(props, state, context)
and most components are nothing without the context part. This is still an oversimplification. The ugly truth is components take input from many other places: API responses, localStorage and window size to name a few.
But we know developing components in isolation is The Way, so intricate inputs won't stop us! With proxies, we look the devil in the eye and mock anything components depend on. Hell, we might even simplify our components once we're aware of all the crazy things they need to work.
How do proxies work? Well duh, they're Just Components. As regular React components, proxies compose in the order they are listed in your config and decorate the loaded component, respecting the contract to render the next proxy in the chain. They can be stateless or have a life cycle, mocking before mounting and unmocking before unmounting.
Proxies have two parts:
- Configuration. Done once per project, inside cosmos.proxies.js. Import proxy packages, call their default export (always a create function) and add the result to the list of exported proxies. Some proxies require options, others work out of the box.
- Activation. Triggered by a special fixture attribute. Eg. The React Router proxy activates when
fixture.url
is defined, otherwise it's a noop. Proxies can also be always-active, but it's a best practice to make proxies opt-in to avoid useless overhead.
Where to put proxies?
As soon as you're ready to add proxies to your Cosmos setup, install them using your package manager. For example:
via npm
1npm install --save-dev react-cosmos-fetch-proxy react-cosmos-redux-proxy react-cosmos-router-proxy
or Yarn
1yarn add --dev react-cosmos-fetch-proxy react-cosmos-redux-proxy react-cosmos-router-proxy
Then create cosmos.proxies.js
(in your project's root directory or next to cosmos.config.js) and export a list of proxies in the order they should load–from outermost to innermost.
cosmos.proxies.js
requires compilation so you may need to place it next to your source files (eg. if thesrc
dir is whitelisted in babel-loader). UseproxiesPath
option to customize its location.
Here's an example where we mock the Fetch API and add Redux and React Router providers:
1// cosmos.proxies.js 2import createFetchProxy from 'react-cosmos-fetch-proxy'; 3import createReduxProxy from 'react-cosmos-redux-proxy'; 4import createRouterProxy from 'react-cosmos-router-proxy'; 5// We can import app files here 6import configureStore from './configureStore'; 7 8// Read more about configuring Redux in the Redux proxy section below 9const ReduxProxy = createReduxProxy({ 10 createStore: state => configureStore(state) 11}); 12 13// We ensure a specific proxy order 14export default [ 15 // Not all proxies have options, and often relying on defaults is good enough 16 createFetchProxy(), 17 ReduxProxy, 18 createRouterProxy() 19];
For details on creating proxies, see the Proxy boilerplate
Jump to:
Context
React Context: With great power comes great responsibility.
Note: React doesn't recommend using context unless you're a lib, so in most cases we're better off using a higher level proxy like the Redux or React Router one.
Configuration
1// cosmos.proxies.js 2import createContextProxy from 'react-cosmos-context-proxy'; 3import PropTypes from 'prop-types'; 4 5const ContextProxy = createContextProxy({ 6 childContextTypes: { 7 theme: PropTypes.object.isRequired 8 } 9}); 10 11export default [ 12 ContextProxy 13 // ...other proxies 14];
Activation
1// __fixtures__/example.js 2export default { 3 component: MyComponent, 4 context: { 5 theme: { 6 backgroundColor: '#f1f1f1', 7 color: '#222' 8 } 9 } 10};
Check out the context example to see the proxy in action.
Redux
react-cosmos-redux-proxy
doesn't work with react-redux v6 yet. If you'd like to help check out this thread.
Most components in a Redux app depend on Redux state, either they're a container or one of their descendants is. This proxy creates a store using initial data from fixtures and puts it in the context, just like the Provider does.
Configuration
1// cosmos.proxies.js 2import createReduxProxy from 'react-cosmos-redux-proxy'; 3import configureStore from './configureStore'; 4 5const ReduxProxy = createReduxProxy({ 6 createStore: state => configureStore(state) 7}); 8 9export default [ 10 ReduxProxy 11 // ...other proxies 12];
Activation
1// __fixtures__/example.js 2export default { 3 component: MyComponent, 4 // An empty object will populate the store with the initial state 5 // returned by reducers. But we can also put any state we want here. 6 reduxState: {} 7};
Writing Redux fixtures almost feels too easy. Because Redux state is global, once we have one state mock we can render any component we want!
React Router
Warning: react-cosmos-router-proxy is designed for React Router v4 and above
React Router is used in most React projects. Wrapping components with withRouter
makes the Router context an implicit dependency–one we need to mock.
Configuration
1// cosmos.proxies.js 2import createRouterProxy from 'react-cosmos-router-proxy'; 3 4export default [ 5 createRouterProxy() 6 // ...other proxies 7];
Activation
Simply adding a url
to your fixture will wrap the loaded component inside a Router.
1// __fixtures__/example.js 2export default { 3 component: MyComponent, 4 url: '/about' 5};
Optionally, route
can be added to also wrap the loaded component inside a Route.
1// __fixtures__/example.js 2export default { 3 component: MyComponent, 4 url: '/users/5', 5 route: '/users/:userId' 6};
If your component needs props from the Route
component (history, location, and match), you can enable the provideRouterProps
flag.
1// __fixtures__/example.js 2export default { 3 component: MyComponent, 4 url: '/users/5', 5 route: '/users/:userId', 6 provideRouterProps: true 7};
Check out the React Router example to see the proxy in action.
React Apollo (GraphQL)
If you use the React integration of Apollo Client to provide data in your app, you may want to:
- Work on your data components in isolation
- Provide static or dynamic mocks to prototype your components
This proxy wraps your components with the ApolloProvider
so they can render in Cosmos like they would normally in your app. Then, you'll be able to consume directly your API or mock its response.
Configuration
Provide:
- The GraphQL
endpoint
you send operations to - Or The
client options object
used in your app
1// cosmos.proxies.js 2import createApolloProxy from 'react-cosmos-apollo-proxy'; 3 4// option 1: specify a graphql endpoint 5 6export default [ 7 createApolloProxy({ 8 endpoint: 'https://my.api.xyz/graphql' 9 }) 10 // ...other proxies 11];
1// cosmos.proxies.js 2import createApolloProxy from 'react-cosmos-apollo-proxy'; 3 4// option 2: use the client from your app 5 6import myConfiguredClientOptions from './src/client.js'; 7 8export default [ 9 createApolloProxy({ 10 clientOptions: myConfiguredClientOptions 11 }) 12 // ...other proxies 13];
"Live" behavior
Once configured, your components enhanced by react-apollo
will behave as they would normally in your app, sending operation via your own client options object or to the endpoint passed specified in cosmos.proxies.js
.
Mocking a response with a result or an error
Mocking at the fixture level is done by specifying an apollo
key in your fixture.
The proxy will look for a resolveWith
or a failWith
key in order to return the appropriate mock value. This mocked return can be one of;
- an object
- a function returning an object
- a function that returns a Promise that either resolves or rejects with an object
See examples below or check the fixtures defined in the Apollo example.
Static response
1export default { 2 component: Author, 3 props: { 4 authorId: 123 5 }, 6 apollo: { 7 resolveWith: { 8 author: { 9 __typename: 'Author', 10 id: 123, 11 firstName: 'Ovidiu' 12 } 13 } 14 } 15};
Dynamic response
1export default { 2 component: Author, 3 props: { 4 authorId: 123 5 }, 6 apollo: { 7 resolveWith: ({ cache, variables, fixture }) => ({ 8 author: { 9 __typename: 'Author', 10 id: variables.authorId, 11 firstName: variables.authorId === 123 ? 'Ovidiu' : 'Xavier' 12 } 13 }) 14 } 15};
Promise response
1export default { 2 component: Author, 3 props: { 4 authorId: 123 5 }, 6 apollo: { 7 resolveWith: ({ cache, variables, fixture }) => 8 Promise.resolve({ 9 author: { 10 __typename: 'Author', 11 id: variables.authorId, 12 firstName: variables.authorId === 123 ? 'Ovidiu' : 'Xavier' 13 } 14 }) 15 } 16};
Named responses
If your fixture's component is enhanced by multiple operations (like a query and a mutation), you can also provide the name of the operation so the proxy knows which response corresponds to which operation.
Below an example with a query & a mutation:
1export default { 2 component: Author, 3 4 props: { 5 authorId: 123 6 }, 7 apollo: { 8 // mocked response for the query named PostsForAuthor 9 PostsForAuthor: { 10 resolveWith: { 11 author: { 12 __typename: 'Author', 13 id: 123, 14 firstName: 'Ovidiu', 15 posts: [ 16 { 17 __typename: 'Post', 18 id: 456, 19 title: 'Testing React Components', 20 votes: 1234 21 }, 22 { 23 __typename: 'Post', 24 id: 789, 25 title: 'When to assert?', 26 votes: 56 27 } 28 ] 29 } 30 } 31 }, 32 // mocked response for the mutation named UpvotePost 33 UpvotePost: { 34 resolveWith: ({ cache, variables, fixture }) => { 35 const data = cache.readQuery({ 36 query: QUERY, 37 variables: { authorId: fixture.props.authorId } 38 }); 39 40 const post = data.author.posts.find( 41 post => post.id === variables.postId 42 ); 43 44 return { 45 upvotePost: { 46 ...post, 47 votes: post.votes + 10 48 } 49 }; 50 } 51 } 52 } 53};
Failing response
You can use the failWith
option to mock an apollo 'networkError', i.e. you did not get a successful response from the server (perhaps the internet connection is offline, or a 500 response was returned):
1export default { 2 component: Author, 3 props: { 4 authorId: 123 5 }, 6 apollo: { 7 failWith: { 8 message: 'Something went bad, please try again!' 9 } 10 } 11};
To mock a valid response from an API which contains an errors object, you can use the following format:
1export default { 2 component: Author, 3 props: { 4 authorId: -1 5 }, 6 apollo: { 7 resolveWith: { 8 data: { 9 author: null 10 }, 11 errors: [ 12 { 13 path: ['author'], 14 message: ['Author id -1 not found'], 15 locations: [{ line: 1, column: 0 }] 16 } 17 ] 18 } 19 } 20};
Check out the Apollo example to see react-cosmos-apollo-proxy
in action! 🚀
Fetch
Besides client-side state, components also depend on external data. Mocking server responses allows us to completely isolate our components. This proxy makes mocking Fetch responses a breeze.
Configuration
1// cosmos.proxies.js 2import createFetchProxy from 'react-cosmos-fetch-proxy'; 3 4export default [ 5 createFetchProxy() 6 // ...other proxies 7];
Activation
1// __fixtures__/example.js 2export default { 3 component: MyComponent, 4 fetch: [ 5 { 6 matcher: '/users', 7 response: [ 8 { 9 id: 1, 10 name: 'Prabu' 11 }, 12 { 13 id: 2, 14 name: 'Karla' 15 }, 16 { 17 id: 3, 18 name: 'Linbaba' 19 } 20 ] 21 } 22 ] 23};
Built on top of fetch-mock. Check out the Fetch example to see the proxy in action.
XHR
Like the Fetch proxy, but for XMLHttpRequest.
Configuration
1// cosmos.proxies.js 2import createXhrProxy from 'react-cosmos-xhr-proxy'; 3 4export default [ 5 createXhrProxy() 6 // ...other proxies 7];
Activation
1// __fixtures__/example.js 2export default { 3 component: MyComponent, 4 xhr: [ 5 { 6 url: '/users', 7 response: (req, res) => 8 res.status(200).body([ 9 { 10 id: 1, 11 name: 'Blossom' 12 }, 13 { 14 id: 2, 15 name: 'Bubbles' 16 }, 17 { 18 id: 3, 19 name: 'Buttercup' 20 } 21 ]) 22 } 23 ] 24};
Built on top of xhr-proxy. Check out the Axios example to see the proxy in action.
LocalStorage
Overrides the global localStorage API with a replica mock.
Mocking localStorage prevents conflicts with existing browser data and enables the localStorage API in test environments like Jest.
Configuration
1// cosmos.proxies.js 2import createLocalStorageProxy from 'react-cosmos-localstorage-proxy'; 3 4export default [ 5 createLocalStorageProxy() 6 // ...other proxies 7];
Activation
1// __fixtures__/example.js 2export default { 3 component: MyComponent, 4 localStorage: { 5 userToken: 'foobar-token' 6 } 7};
More proxies
Other proxies created by the Cosmos community:
- alp82/react-cosmos-glamorous-proxy A simple proxy for react-cosmos to load glamorous themes
- jozsi/react-cosmos-wrapper-proxy Easily wrap components using react-cosmos
- concept-not-found/react-cosmos-reach-router-proxy A proxy for @reach/router
- react-intl-proxy A proxy for yahoo/react-intl
- simeonc/react-cosmos-background-proxy A simple proxy for applying global styles and modifying the fixture background (via applying styles on the playground iFrame body)
- omarzion/react-cosmos-stateful-proxy A simple proxy wrapper to handle state for stateless components
What proxy would you create to improve DX?
Integration with popular tools
Create React App
Add react-cosmos-classic
to dev dependencies and create cosmos.config.js
.
1// cosmos.config.js 2module.exports = { 3 containerQuerySelector: '#root', 4 webpackConfigPath: 'react-scripts/config/webpack.config', 5 publicPath: 'public', 6 // Optional: Add this when you start using proxies 7 proxiesPath: 'src/cosmos.proxies' 8};
Note: When using an older version than
react-scripts@2.1.2
thewebpackConfigPath
has to be set to'react-scripts/config/webpack.config.dev'
If you are using the NODE_PATH
environment variable for absolute imports, make sure to include that as part of the cosmos script:
1// package.json 2"scripts": { 3 "cosmos": "NODE_PATH=./src cosmos-classic" 4}
Also make sure to:
- Put proxies in the
src
dir–the only place included by the CRA Babel loader
CRA + Cosmos example: Flatris
With react-app-rewired
1// cosmos.config.js 2+const overrides = require('react-app-rewired/config-overrides'); 3 4module.exports = { 5 containerQuerySelector: '#root', 6 webpackConfigPath: 'react-scripts/config/webpack.config.dev', 7+ webpack: config => overrides.webpack(config), 8 publicPath: 'public', 9 // Optional: Add this when you start using proxies 10 proxiesPath: 'src/cosmos.proxies' 11};
Github Pages and Jekyll
You can publish Cosmos publicly using Github pages by using cosmos-export
. Commit the exported files to a /docs/
folder in the root of your project and you should be good to go.
When you deploy to Github pages, it defaults to using Jekyll and this will cause problems for Cosmos because Jekyll filters out files that start with an underscore so _playground.js
and other files will be gone when index.html
needs them
The solution is to put an empty .nojekyll
file in your /public/
folder. This will turn off Jekyll rendering and Cosmos should work just fine.
Next.js
Add react-cosmos-classic
to dev dependencies and create cosmos.config.js
.
Next.js apps run on both client & server, so compilation is done via Babel plugins instead of webpack loaders. This means we can rely on Cosmos' default webpack config.
1// cosmos.config.js 2module.exports = { 3 publicPath: 'static', 4 publicUrl: '/static/' 5};
Also make sure to:
- Add
html-webpack-plugin
to your dev dependencies - Define
.babelrc
for the Cosmos webpack config to rely on the Next.js preset:
1{ 2 "presets": ["next/babel"] 3}
Next.js + Cosmos example: Illustrated Algorithms
React Boilerplate
Add react-cosmos-classic
to dev dependencies and create cosmos.config.js
.
1// cosmos.config.js 2module.exports = { 3 containerQuerySelector: '#app', 4 webpackConfigPath: './internals/webpack/webpack.dev.babel', 5 globalImports: ['./app/global-styles.js'] 6};
React Redux Starter Kit
Add react-cosmos-classic
to dev dependencies and create cosmos.config.js
.
1// cosmos.config.js 2module.exports = { 3 webpackConfigPath: 'build/webpack.config.js' 4};
Also make sure to:
- Set up the Redux proxy :)
Config
The Cosmos config is optional, but it's very likely you'll want to create one at some point to set some custom options. The standard approach is to put a cosmos.config.js
file in your project root.
Custom config path
Use the --config
CLI arg if you prefer not placing the config in the project root.
1// package.json 2"scripts": { 3 "cosmos": "cosmos --config path/to/cosmos.config.js" 4}
Set the rootPath
option to match the project root when using a custom config path. All other paths defined in the config are relative to rootPath.
1// cosmos.config.js 2module.exports = { 3 rootPath: '../../' 4};
Custom webpack config
The default webpack config included in Cosmos checks to see which packages you have installed and, if found, automatically includes the Babel, CSS and JSON loaders, as well as the HtmlWebpackPlugin.
If you already have a hairy webpack config that you'd like to reuse, set the webpackConfigPath
option to your webpack config's file path and Cosmos will do its best to extend it.
1// cosmos.config.js 2module.exports = { 3 webpackConfigPath: './config/webpack.config.dev.js' 4};
You can also customize your webpack config specifically for Cosmos. Eg. Omitting one plugin from the Cosmos build.
1// cosmos.config.js 2module.exports = { 3 webpack: (config, { env }) => { 4 // Return customized config 5 return { 6 ...config, 7 plugins: config.plugins.filter( 8 p => !p.constructor || p.constructor.name !== 'OfflinePlugin' 9 ) 10 }; 11 } 12};
Custom fixture paths
The fileMatch
, fileMatchIgnore
and exclude
options are used to detect fixture files. The default fileMatch
value is meant to accommodate most needs out of the box:
'**/__fixture?(s)__/**/*.{js,jsx,ts,tsx}',
'**/?(*.)fixture?(s).{js,jsx,ts,tsx}'
The default fileMatchIgnore
value is meant to ignore node_modules folder:
'**/node_modules/**'
Note: Set the
rootPath
to a dir parent to all fixture files when using a custom config path
TODO: Add fixtureDir
and fixtureSuffix
options for easier file match customization #488
Option dump
Options supported by cosmos.config.js
.
1// cosmos.config.js 2module.exports = { 3 // Set all other paths relative this this one. Important when cosmos.config 4 // isn't placed in the project root 5 rootPath: '../', 6 7 // Additional entry points that should be present along with any component 8 // Sad, but inevitable 9 globalImports: ['./reset.css', './global.css', 'babel-polyfill'], 10 11 // Customize pattern(s) for matching fixture files 12 fileMatch: ['**/fixtures-in-here/**/*.js'], 13 14 // Fixtures will not be loaded in the playground if their names match these 15 exclude: [/not-a-fixture/, /its-complicated/, /its-not-me-its-you/], 16 17 // File path to serve static files from. Like --content-base in webpack-dev-server 18 publicPath: 'src/public', 19 20 // Set base URL for both webpack assets and static files from publicPath 21 // Maps to webpack.output.publicPath 22 // https://webpack.js.org/configuration/output/#output-publicpath 23 publicUrl: '/static/', 24 25 // Customize proxies file path. Useful if Babel doesn't compile the root dir 26 proxiesPath: 'src/proxies.cosmos', 27 28 // Render inside custom root element. Useful if that root element already 29 // has styles attached, but bad for encapsulation 30 containerQuerySelector: '#app', 31 32 // Disable hot module replacement 33 hot: false, 34 35 // HTTP proxy specific requests to a different target 36 // For advanced usage see https://github.com/react-cosmos/react-cosmos/pull/875 37 httpProxy: { 38 context: '/api', 39 target: 'http://localhost:4000/api' 40 }, 41 42 // Reuse existing webpack config 43 webpackConfigPath: './config/webpack.config.dev', 44 45 // Customize webpack config 46 webpack: (config, { env }) => { 47 // Return customized config 48 return config; 49 }, 50 51 // Specify where should webpack watch for fixture files (defaults to rootPath) 52 watchDirs: ['src'], 53 54 // Customize dev server 55 hostname: 'localhost', 56 port: 8989 57};
Exporting
Static Component Playground? Piece of 🍰!
Add this script and run npm run cosmos:export
or yarn cosmos:export
.
1"scripts": { 2+ "cosmos:export": "cosmos-classic-export" 3}
Now you can deploy the cosmos-export
directory to any static hosting service.
Use http-server or any static file server to load the export locally.
Headless testing
Add
react-cosmos-test
to your dev dependencies for this API.
Besides showing up in the Playground UI, fixtures can also be used independently to render a component in a mocked environment.
Using Enzyme
The test API exposes an entry point specifically designed for Enzyme.
1import createTestContext from 'react-cosmos-test/enzyme'; 2import fixture from './fixture'; 3 4const { mount, getWrapper } = createTestContext({ fixture }); 5 6beforeEach(mount); 7 8test('renders hello', () => { 9 expect(getWrapper().text()).toContain('Hello World'); 10});
Enzyme v3 requires us to call
wrapper.update
after a component updates, usually in response to an event (see thread). Thereact-cosmos-test/enzyme
wrapper tries to alleviate this by updating the wrapper whenever we callgetWrapper()
. If your components don't seem to be updating in tests this may be due to to assigninggetWrapper()
to a variable and expecting it to change.
But this is not the only way. As we'll see below, we can also mount fixtures using a custom renderer.
Using a custom renderer
Here's how to render a fixture with good ol' react-test-renderer.
1import { create as renderer } from 'react-test-renderer'; 2import createTestContext from 'react-cosmos-test/generic'; 3import fixture from './fixture'; 4 5const { mount, getWrapper } = createTestContext({ 6 renderer, 7 fixture 8}); 9 10beforeEach(mount); 11 12test('matches snapshot', () => { 13 // Careful, this is no longer an Enzyme wrapper, but a react-test-renderer wrapper! 14 expect(getWrapper().toJSON()).toMatchSnapshot(); 15});
Capturing state changes
The fixture does more than just defining component input. Like a sticky fly trap, the fixture captures state changes that occur during the component's lifecycle, which we can then inspect. For example:
- If Redux state changes, the latest state can be read via
get('reduxState')
- If Router URL changes, the latest URL can be read via
get('url')
Instead of polluting our tests with various store and provider initialization, we let the Proxies take care of it and then collect state changes from the updated fixture.
The following example assumes
react-cosmos-router-proxy
is configured.
1import createTestContext from 'react-cosmos-test/enzyme'; 2import fixture from '../__fixtures__/logged-in'; 3 4const { mount, getWrapper, get } = createTestContext({ fixture }); 5 6beforeEach(mount); 7 8test('redirects to home page after signing out', () => { 9 getWrapper('.logout-btn').simulate('click'); 10 11 expect(get('url')).toBe('/'); 12});
Updating fixtures in tests
Sometimes we want to test that a component updates correctly in response to prop changes. We can use setProps
to pass new props to a component. setProps
merges passed in props with existing props.
1import createTestContext from 'react-cosmos-test/enzyme'; 2import fixture from '../__fixtures__/button'; 3 4const { mount, getWrapper, setProps } = createTestContext({ fixture }); 5 6beforeEach(mount); 7 8test('responds to props being updated', () => { 9 expect(getWrapper('.btn').hasClass('warning')).toBeFalsy(); 10 setProps({ warning: true }); 11 expect(getWrapper('.btn').hasClass('warning')).toBeTruthy(); 12});
createTestContext API
The createTestContext API makes use of already configured proxies, which can be included in more ways.
1// Detect proxies automatically by reading cosmos config from cwd (or via --config CLI arg)
2const { mount } = createTestContext({ fixture });
3
4// Or point to a custom config path
5const { mount } = createTestContext({
6 fixture,
7 cosmosConfigPath: '/path/to/my/special/config';
8});
9
10// Or pass proxies directly
11const { mount } = createTestContext({ fixture, proxies });
12
13// By default we auto apply jest.fn to all functions in fixture.props recursively.
14// This makes it possible to do expect(fixture.props.*).toHaveBeenCalled in Jest
15// without wrapping any callback with jest.fn() by hand.
16// If this causes issues you can disable this feature, for example the case in https://github.com/react-cosmos/react-cosmos/issues/658
17const { mount } = createTestContext({ fixture, autoMockProps: false });
Context methods
- async
mount
Mounts component via renderer (usually called inbeforeEach
) unmount
Calls unmount method of wrapper returned by renderergetWrapper
Returns wrapper returned by renderergetRef
Get component ref (exclusively for Class components)getField(fixtureKey)
(orget
for brevity) Returns updated fixture fieldsetProps(newProps)
Merges passed in props with existing fixture props (triggers re-render)
Global Jest snapshot
You can create a snapshot of all your components with react-cosmos-telescope
. A single snapshot file for all components isn't ideal, but it makes a difference until you have time to create granular tests.
1import runTests from 'react-cosmos-telescope';
2
3runTests({
4 cosmosConfigPath: require.resolve('./cosmos.config.js')
5});
Beta: React Native
Follow these steps once you have
react-cosmos
installed.
Add package.json script
1"scripts": { 2+ "cosmos-native": "cosmos-native" 3}
(Temporarily) Replace App.js
(your app's entry point) with this:
1import React, { Component } from 'react'; 2import { CosmosNativeLoader } from 'react-cosmos-loader/native'; 3import { options, getUserModules } from './cosmos.modules'; 4 5export default class App extends Component { 6 render() { 7 return <CosmosNativeLoader options={options} modules={getUserModules()} />; 8 } 9}
Start your native app's dev server, and in another terminal run npm run cosmos-native
or yarn cosmos-native
and go to localhost:8989 🔥
Since ___fixtures___ dirs are blacklisted by default in RN, you may need to override the
getBlacklistRE
setting.
1// rn-cli.config.js 2const blacklist = require('metro/src/blacklist'); 3 4module.exports = { 5 getBlacklistRE() { 6 // __fixtures__ are blacklisted by default 7 return blacklist([]); 8 } 9};
Next steps:
- Add auto-generated file
cosmos.modules.js
to gitignore - Split App.js into
App.cosmos.js
andApp.main.js
— Check out the CRNA example for inspiration - Report an issue or share some feedback
Flow integration
Note: The
createFixture
helper only type checks fixture.props. It's not able to validate other fixture fields that map to custom proxies, but it still provides great value in many cases.
1import { createFixture } from 'react-cosmos-classic';
2import { Button } from '.';
3
4export default createFixture({
5 component: Button,
6 props: {
7 label: 'Press me',
8 disabled: 'false'
9 // Cannot call createFixture with object literal bound to fixture because
10 // string [1] is incompatible with boolean [2] in property props.disabled.
11 }
12});
Warning: Prop types are lost when using fixtures for components wrapped in higher order components.
Join the component revolution!
This project welcomes all. Check out the Contributing Guide to read about the project's mission and how to get involved. Ask anything on Slack. Let's make UI development fun!
Thanks to Kreativa Studio for the Cosmos logo.
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: MIT License: LICENSE:0
Reason
Found 2/30 approved changesets -- score normalized to 0
Reason
project is archived
Details
- Warn: Repository is archived.
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'master'
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 6 are checked with a SAST tool
Reason
190 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92
- Warn: Project is vulnerable to: GHSA-6chw-6frg-f759
- Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw
- Warn: Project is vulnerable to: GHSA-whgm-jr23-g3j9
- Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw
- Warn: Project is vulnerable to: GHSA-w42g-7vfc-xf37
- Warn: Project is vulnerable to: GHSA-j5g3-5c8r-7qfx
- Warn: Project is vulnerable to: GHSA-fwr7-v2mv-hh25
- Warn: Project is vulnerable to: GHSA-8w4h-3cm3-2pm2
- Warn: Project is vulnerable to: GHSA-42xw-2xvc-qx8m
- Warn: Project is vulnerable to: GHSA-4w2v-q235-vp99
- Warn: Project is vulnerable to: GHSA-cph5-m8f7-6c5x
- Warn: Project is vulnerable to: GHSA-wf5p-g6vw-rhxx
- Warn: Project is vulnerable to: GHSA-2mj8-pj3j-h362
- Warn: Project is vulnerable to: GHSA-gqf6-75v8-vr26
- Warn: Project is vulnerable to: GHSA-v45m-2wcp-gg98
- Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7
- Warn: Project is vulnerable to: GHSA-cwfw-4gq5-mrqx
- Warn: Project is vulnerable to: GHSA-g95f-p29q-9xw4
- Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg
- Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw
- Warn: Project is vulnerable to: GHSA-w8qv-6jwh-64r5
- Warn: Project is vulnerable to: GHSA-hc9w-4p87-j549
- Warn: Project is vulnerable to: GHSA-wg6g-ppvx-927h
- Warn: Project is vulnerable to: GHSA-c6rq-rjc2-86v2
- Warn: Project is vulnerable to: GHSA-wxhq-pm8v-cw75
- Warn: Project is vulnerable to: GHSA-mh2h-6j8q-x246
- Warn: Project is vulnerable to: GHSA-5q88-cjfq-g2mh / GHSA-xp63-6vf5-xf3v
- Warn: Project is vulnerable to: GHSA-4gw3-8f77-f72c
- Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
- Warn: Project is vulnerable to: GHSA-rq8g-5pc5-wrhr
- Warn: Project is vulnerable to: GHSA-p28h-cc7q-c4fg
- Warn: Project is vulnerable to: GHSA-9vvw-cc9w-f27h
- Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c
- Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq
- Warn: Project is vulnerable to: GHSA-hr2v-3952-633q
- Warn: Project is vulnerable to: GHSA-ff7x-qrg7-qggm
- Warn: Project is vulnerable to: GHSA-vh7m-p724-62c2
- Warn: Project is vulnerable to: GHSA-r9p9-mrjm-926w
- Warn: Project is vulnerable to: GHSA-434g-2637-qmqr
- Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m
- Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw
- Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p
- Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747
- Warn: Project is vulnerable to: GHSA-j4f2-536g-r55m
- Warn: Project is vulnerable to: GHSA-r7qp-cfhv-p84w
- Warn: Project is vulnerable to: GHSA-4gmj-3p3h-gm8h
- Warn: Project is vulnerable to: GHSA-3gx7-xhv7-5mx3
- Warn: Project is vulnerable to: GHSA-6h5x-7c5m-7cr7
- Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc
- Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx
- Warn: Project is vulnerable to: GHSA-qrmc-fj45-qfc2
- Warn: Project is vulnerable to: GHSA-74fj-2j2h-c42q
- Warn: Project is vulnerable to: GHSA-pw2r-vq6v-hr8c
- Warn: Project is vulnerable to: GHSA-jchw-25xp-jwwc
- Warn: Project is vulnerable to: GHSA-cxjh-pqwp-8mfp
- Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3
- Warn: Project is vulnerable to: MAL-2023-462
- Warn: Project is vulnerable to: GHSA-xf7w-r453-m56c
- Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97
- Warn: Project is vulnerable to: GHSA-q42p-pg8m-cqh6
- Warn: Project is vulnerable to: GHSA-w457-6q6x-cgp9
- Warn: Project is vulnerable to: GHSA-62gr-4qp9-h98f
- Warn: Project is vulnerable to: GHSA-f52g-6jhx-586p
- Warn: Project is vulnerable to: GHSA-2cf5-4w76-r9qv
- Warn: Project is vulnerable to: GHSA-3cqr-58rm-57f8
- Warn: Project is vulnerable to: GHSA-g9r4-xpmj-mj65
- Warn: Project is vulnerable to: GHSA-q2c6-c6pm-g3gh
- Warn: Project is vulnerable to: GHSA-765h-qjxv-5f44
- Warn: Project is vulnerable to: GHSA-f2jv-r9rf-7988
- Warn: Project is vulnerable to: GHSA-44pw-h2cw-w3vq
- Warn: Project is vulnerable to: GHSA-jp4x-w63m-7wgm
- Warn: Project is vulnerable to: GHSA-c429-5p7v-vgjp
- Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj
- Warn: Project is vulnerable to: GHSA-pfq8-rq6v-vf5m
- Warn: Project is vulnerable to: GHSA-rc47-6667-2j5j
- Warn: Project is vulnerable to: GHSA-6x33-pw7p-hmpq
- Warn: Project is vulnerable to: GHSA-c7qv-q95q-8v27
- Warn: Project is vulnerable to: GHSA-pc5p-h8pf-mvwp
- Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37
- Warn: Project is vulnerable to: GHSA-78xj-cgh5-2h22
- Warn: Project is vulnerable to: GHSA-2p57-rm9w-gvfp
- Warn: Project is vulnerable to: GHSA-2pr6-76vf-7546
- Warn: Project is vulnerable to: GHSA-8j8c-7jfh-h6hx
- Warn: Project is vulnerable to: GHSA-896r-f27r-55mw
- Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h
- Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp
- Warn: Project is vulnerable to: GHSA-76p3-8jx3-jpfq
- Warn: Project is vulnerable to: GHSA-3rfm-jhwj-7488
- Warn: Project is vulnerable to: GHSA-hhq3-ff78-jv3g
- Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695
- Warn: Project is vulnerable to: GHSA-fvqr-27wr-82fm
- Warn: Project is vulnerable to: GHSA-4xc9-xhrj-v574
- Warn: Project is vulnerable to: GHSA-x5rq-j2xg-h7qm
- Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw
- Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9
- Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm
- Warn: Project is vulnerable to: GHSA-h726-x36v-rx45
- Warn: Project is vulnerable to: GHSA-4xcv-9jjx-gfj3
- Warn: Project is vulnerable to: GHSA-f9cm-qmx5-m98h
- Warn: Project is vulnerable to: GHSA-7wpw-2hjm-89gp
- Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv
- Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3
- Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m / GHSA-xvch-5gv4-984h
- Warn: Project is vulnerable to: GHSA-3mpr-hq3p-49h9
- Warn: Project is vulnerable to: GHSA-fhjf-83wg-r2j9
- Warn: Project is vulnerable to: GHSA-8hfj-j24r-96c4
- Warn: Project is vulnerable to: GHSA-wc69-rhjr-hc9g
- Warn: Project is vulnerable to: GHSA-gwg9-rgvj-4h5j
- Warn: Project is vulnerable to: GHSA-w9mr-4mfr-499f
- Warn: Project is vulnerable to: GHSA-r683-j2x4-v87g
- Warn: Project is vulnerable to: GHSA-w7rc-rwvf-8q5r
- Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p
- Warn: Project is vulnerable to: GHSA-jmqm-f2gx-4fjv
- Warn: Project is vulnerable to: GHSA-rp65-9cf3-cjxr
- Warn: Project is vulnerable to: GHSA-6394-6h9h-cfjg
- Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9
- Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j
- Warn: Project is vulnerable to: GHSA-pgcr-7wm4-mcv6
- Warn: Project is vulnerable to: GHSA-4cpg-3vgw-4877
- Warn: Project is vulnerable to: GHSA-566m-qj78-rww5
- Warn: Project is vulnerable to: GHSA-hwj9-h5mp-3pm3
- Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j
- Warn: Project is vulnerable to: GHSA-6fw4-hr69-g3rv
- Warn: Project is vulnerable to: GHSA-gqgv-6jq5-jjj9
- Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp
- Warn: Project is vulnerable to: GHSA-hxcm-v35h-mg2x
- Warn: Project is vulnerable to: GHSA-5q6m-3h65-w53x
- Warn: Project is vulnerable to: GHSA-rxrc-rgv4-jpvx
- Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6
- Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw
- Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg
- Warn: Project is vulnerable to: GHSA-h9rv-jmmf-4pgx
- Warn: Project is vulnerable to: GHSA-hxcc-f52p-wc94
- Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p
- Warn: Project is vulnerable to: GHSA-jv35-xqg7-f92r
- Warn: Project is vulnerable to: GHSA-4g88-fppr-53pp
- Warn: Project is vulnerable to: GHSA-4jqc-8m5r-9rpr
- Warn: Project is vulnerable to: GHSA-g4rg-993r-mgx7
- Warn: Project is vulnerable to: GHSA-3f95-r44v-8mrg
- Warn: Project is vulnerable to: GHSA-28xr-mwxg-3qc8
- Warn: Project is vulnerable to: GHSA-9p95-fxvg-qgq2
- Warn: Project is vulnerable to: GHSA-9w5j-4mwv-2wj8
- Warn: Project is vulnerable to: GHSA-gff7-g5r8-mg8m
- Warn: Project is vulnerable to: GHSA-fxwf-4rqh-v8g3
- Warn: Project is vulnerable to: GHSA-25hc-qcg6-38wj
- Warn: Project is vulnerable to: GHSA-xfhh-g9f5-x4m4
- Warn: Project is vulnerable to: GHSA-qm95-pgcg-qqfq
- Warn: Project is vulnerable to: GHSA-cqmj-92xf-r6r9
- Warn: Project is vulnerable to: GHSA-2m39-62fm-q8r3
- Warn: Project is vulnerable to: GHSA-vx3p-948g-6vhq
- Warn: Project is vulnerable to: GHSA-mf6x-7mm4-x2g7
- Warn: Project is vulnerable to: GHSA-j44m-qm6p-hp7m
- Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9
- Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh
- Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36
- Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw
- Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc
- Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p
- Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc
- Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v
- Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3
- Warn: Project is vulnerable to: GHSA-7p7h-4mm5-852v
- Warn: Project is vulnerable to: GHSA-38fc-wpqx-33j7
- Warn: Project is vulnerable to: GHSA-662x-fhqg-9p8v
- Warn: Project is vulnerable to: GHSA-394c-5j6w-4xmx
- Warn: Project is vulnerable to: GHSA-78cj-fxph-m83p
- Warn: Project is vulnerable to: GHSA-fhg7-m89q-25r3
- Warn: Project is vulnerable to: GHSA-cf4h-3jhx-xvhq
- Warn: Project is vulnerable to: GHSA-pv4c-p2j5-38j4
- Warn: Project is vulnerable to: GHSA-46c4-8wrp-j99v
- Warn: Project is vulnerable to: GHSA-9m6j-fcg5-2442
- Warn: Project is vulnerable to: GHSA-hh27-ffr2-f2jc
- Warn: Project is vulnerable to: GHSA-rqff-837h-mm52
- Warn: Project is vulnerable to: GHSA-8v38-pw62-9cw2
- Warn: Project is vulnerable to: GHSA-hgjh-723h-mx2j
- Warn: Project is vulnerable to: GHSA-jf5r-8hm2-f872
- Warn: Project is vulnerable to: GHSA-wr3j-pwj9-hqq6
- Warn: Project is vulnerable to: GHSA-g78m-2chm-r7qv
- Warn: Project is vulnerable to: GHSA-5v72-xg48-5rpm
- Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q
- Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693
- Warn: Project is vulnerable to: GHSA-h6q6-9hqw-rwfv
- Warn: Project is vulnerable to: GHSA-5fg8-2547-mr8q
- Warn: Project is vulnerable to: GHSA-crh6-fp67-6883
- Warn: Project is vulnerable to: GHSA-72mh-269x-7mh5
- Warn: Project is vulnerable to: GHSA-h4j5-c7cj-74xg
- Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh
- Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp
Score
1.7
/10
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn MoreOther packages similar to react-cosmos-apollo-proxy
@apollo/client
A fully-featured caching GraphQL client.
apollo-upload-client
A terminating Apollo Link for Apollo Client that fetches a GraphQL multipart request if the GraphQL variables contain files (by default FileList, File, or Blob instances), or else fetches a regular GraphQL POST or GET request (depending on the config and
@apollo/react-hooks
React Apollo Hooks.
apollo-client
A simple yet functional GraphQL client.