A clear and concise description of what the bug is.
Apologies if this is not the right place to post this, but I have seen a similar issue posted on the Expo Github, so I figured I would post it on the framework in question. In short, the issue is that I can't get the UI-Kitten library to work with NextJS using react-native-web (the latter working fine without UI-Kitten). When creating a project based on with-react-native-web, and installing the dependencies, yarn add @ui-kitten/components@next @eva-design/eva@next react-native-svg, I get the following error when trying to use the library:
Error: Cannot find module 'react-native'
Require stack:
- /Users/andersravn/plantjammer/ui-kitten/node_modules/@ui-kitten/components/theme/modal/modalPanel.component.js
- /Users/andersravn/plantjammer/ui-kitten/node_modules/@ui-kitten/components/theme/application/applicationProvider.component.js
- /Users/andersravn/plantjammer/ui-kitten/node_modules/@ui-kitten/components/theme/index.js
- /Users/andersravn/plantjammer/ui-kitten/node_modules/@ui-kitten/components/index.js
- /Users/andersravn/plantjammer/ui-kitten/.next/server/static/development/pages/index.js
- /Users/andersravn/plantjammer/ui-kitten/node_modules/next/dist/next-server/server/require.js
- /Users/andersravn/plantjammer/ui-kitten/node_modules/next/dist/next-server/server/load-components.js
- /Users/andersravn/plantjammer/ui-kitten/node_modules/next/dist/next-server/server/api-utils.js
- /Users/andersravn/plantjammer/ui-kitten/node_modules/next/dist/next-server/server/next-server.js
- /Users/andersravn/plantjammer/ui-kitten/node_modules/next/dist/server/next.js
- /Users/andersravn/plantjammer/ui-kitten/node_modules/next/dist/server/lib/start-server.js
- /Users/andersravn/plantjammer/ui-kitten/node_modules/next/dist/cli/next-dev.js
- /Users/andersravn/plantjammer/ui-kitten/node_modules/next/dist/bin/next
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:625:15)
at Function.Module._load (internal/modules/cjs/loader.js:527:27)
at Module.require (internal/modules/cjs/loader.js:683:19)
at require (internal/modules/cjs/helpers.js:16:16)
at Object.<anonymous> (/Users/andersravn/plantjammer/ui-kitten/node_modules/@ui-kitten/components/theme/modal/modalPanel.component.js:12:24)
at Module._compile (internal/modules/cjs/loader.js:777:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:788:10)
at Module.load (internal/modules/cjs/loader.js:643:32)
at Function.Module._load (internal/modules/cjs/loader.js:556:12)
at Module.require (internal/modules/cjs/loader.js:683:19)
at require (internal/modules/cjs/helpers.js:16:16)
at Object.<anonymous> (/Users/andersravn/plantjammer/ui-kitten/node_modules/@ui-kitten/components/theme/application/applicationProvider.component.js:15:32)
at Module._compile (internal/modules/cjs/loader.js:777:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:788:10)
at Module.load (internal/modules/cjs/loader.js:643:32)
at Function.Module._load (internal/modules/cjs/loader.js:556:12)
I have made a repo to reproduce the error: https://github.com/andersravn/ui-kitten-nextjs.
NextJS, with webpack/babel configuration, parses react-native imports as react-native-web in order to use the ui-kitten library.
Using the same libraries, react-native-web and ui-kitten, with create-react-app works as expected, so that's why I'm guessing it's something to do with the way NextJS parses the library files? I know very little about babel and webpack, but from reading here, it seems to have something to do with this.
Thanks for a great product.
3 hours later, I'm facing the same issue. Timing is everything.
I found the cause. It's because ui-kitten hasn't been transpiled yet. I also found a fix. I don't know if it's a workaround or a solution but this appears to be working for me.
npm i --save next-compose-plugins next-transpile-modules
next.config.jsconst withPlugins = require('next-compose-plugins');
const withTM = require('next-transpile-modules')(['@ui-kitten/components', 'react-native-svg']);
module.exports = withPlugins([withTM], {
webpack: config => {
config.resolve.alias = {
...(config.resolve.alias || {}),
// Transform all direct `react-native` imports to `react-native-web`
'react-native$': 'react-native-web',
}
config.resolve.extensions = [
'.web.js',
'.web.ts',
'.web.tsx',
...config.resolve.extensions,
]
return config
},
});
From what I've seen you'll have to add all modules that need to be transpiled to the array. It gets a bit slower though, but it's not by a whole lot.
@andersravn Thought I'd add proof in the shape of a screenshot.

Code:
import * as React from 'react'
import Link from 'next/link'
import { StyleSheet, Text, View } from 'react-native'
import { Button } from '@ui-kitten/components'
export default function App(props) {
return (
<View style={styles.container}>
<Text accessibilityRole="header" style={styles.text}>
React Native for Web & Next.js
</Text>
<Link style={styles.link} accessibilityRole="link" href={`/alternate`}>
A universal link
</Link>
<Button status='primary'>PRIMARY</Button>
<View style={styles.textContainer}>
<Text accessibilityRole="header" aria-level="2" style={styles.text}>
Subheader
</Text>
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
alignItems: 'center',
flexGrow: 1,
justifyContent: 'center',
},
link: {
color: 'blue',
},
textContainer: {
alignItems: 'center',
marginTop: 16,
},
text: {
alignItems: 'center',
fontSize: 24,
marginBottom: 24,
},
})
Update: At some point I have to stop commenting, so I'll start editing this message.
I also found that you have to replace the "links" in the example, otherwise the page will do a hard refresh. What works for me is just adding Link. I've updated the code snippet to reflect this.
Update 2: In case anyone else ends up here, my statement is a bit misleading. The above snippets aren't enough to get the button to show up. You have to also add a new file: pages/_app.js with the following contents:
import { ApplicationProvider, Layout, Text } from '@ui-kitten/components';
import { mapping, light as lightTheme } from '@eva-design/eva';
function MyApp({ Component, pageProps }) {
return (
<ApplicationProvider mapping={mapping} theme={lightTheme}>
<Component {...pageProps} />
</ApplicationProvider>
)
}
export default MyApp
@RWOverdijk Wonderful! That worked. Thank you so much for getting back to me after trying out for yourself, and then giving such a thorough answer. I also spent several hours on my own before I decided to make this issue. This helped me out a ton. This should be a starter example. 馃槃
@RWOverdijk how has your experience been working further with this setup? I've found that the <ApplicationProvider> takes a significant ~400ms to render, slowing down a page significantly.
My experience with all of it is that it feeks forced and hacky and I am looking into different approaches altogether.
I want to share components between platforms but I don't want that to come with a massive burden (think RN web and UI kitten). So I'm working on a way to share the logic and even styling between the two platforms but have the structural logic be separate (View vs div for example).
I think I'm on to something here but... Who knows.
Ah, interesting approach. Can you give some more hints to what you are using to achieve this? I had the same goal as we have started using UI Kitten in our Expo app, and will be replicating some of the screens on our website. Perhaps I should just look into Expo Web for that.
I started on expo web, but quickly found the bundle size to be abnormally large. Our website is almost 4MB. On top of that prerendering (which is what you'll need for unfurling and OG reading) doesn't work properly (and requires a lot of work to get decent).
Next is the right way I think.
In regards of my approach, it's still not done but I am looking into exported style objects (just POJO) and then a template file (much like .web.js and .ios.js) for web and mobile. They both use the styles their own way (StyleSheet.create and style modules in next). It does mean I have some work to do in terms of a style system for web, but that's the cost so far...
@andersonleite
takes a significant ~400ms to render
Take a look at this guide to speed-up the application start
It has no "out of the box" optimization for the webpack, but I guess you can achieve same result by using CLI, which we announced recently ;)
@artyorsh Thanks for chipping in. Can't seem to get it to work. I installed yarn add -D @ui-kitten/metro-config and ran ui-kitten bootstrap @eva-design/eva and just get command not found: ui-kitten.
@andersravn oops. Could you please add an npm script with same code and try using it?
like
"scripts": {
"bootstrap": "ui-kitten bootstrap @eva-design/eva"
}
and then
yarn bootstrap
# npm?
# npm run bootstrap
@artyorsh Nice. That definitely sped it up significantly. Down to ~20ms. 馃槷 Thanks, and also for the great work you guys are doing on UI Kitten. 馃槃
Oh heck yes, I did not know that. 馃槃
@artyorsh It does look like customMappingPath needs to be json for metro, and I'm using js everywhere. But maybe that changed for v5, I'm still on v4.
@RWOverdijk yes, it should. We can't allow js for multiple reasons. Please open an issue in our repo if you still have questions on it
Most helpful comment
I found the cause. It's because ui-kitten hasn't been transpiled yet. I also found a fix. I don't know if it's a workaround or a solution but this appears to be working for me.
npm i --save next-compose-plugins next-transpile-modulesnext.config.jsFrom what I've seen you'll have to add all modules that need to be transpiled to the array. It gets a bit slower though, but it's not by a whole lot.