Experimental project demonstrating Snack in custom native runtimes
App — Start it — Customize it — Examples — Caveats — Common Errors
This demo app uses expo-dev-clients
and contains the Snack Runtime to load and render Snacks.
-
src/assets
- The default assets necessary to build the app, configured through app.json -
src/providers
- Containing the theme and navigation providers, used in App.tsx -
src/screens
- Separate screens all working together, most interesting one is screens/Snack.tsx -
src/types
- Containing shared TypeScript files -
src/App.tsx
- The main app entrypoint
To get your hands dirty, follow these steps.
-
$ npm i -g expo-cli
- Make sure you installed the expo-cli -
$ yarn install
- Install all modules with yarn -
$ yarn run postinstall
- Should run automatically, but in some cases it doesn't 🤷
-
$ expo run:android --device
- Builds the app on an emulator or real deviceadb devices -l
- Real devices have to be usb-connected and listed under that command - Follow the steps in the terminal
In some occasions, the app might close when running
expo run:android
. If you manually open the app again, and scan the QR code from your terminal, it should work fine.
-
$ expo run:ios --device
- Builds the app on a simulator or real device, devices have to be usb-connected - Follow the steps in the terminal
You should be able to add any native modules to the app. Install it, add the required native code, and run the above Android and/or iOS commands.
If the native module has a config plugin, you can remove the /android and /ios folders and run the above commands again.
Here are some Snacks that you can use as inspiration, and load it in the client.
- Default Snack - Just the default code when creating a new Snack (JS-only with assets)
- Blurhash Snack - Simple React Native Blurhash example (custom native code)
Snack assumes that certain native modules are preinstalled. Although this works well for Expo Go, using a custom native runtime brings some added complexity to this assumption.
Every module that requires native code has to be installed natively before it can be used in the loaded Snack
This means that if you want to use expo-location in the Snack you want to load, it has to be installed in the native build before you can use it.
Snack uses a node module bundler called "Snackager". Snackager will automatically build a JS-only bundle if you include it in your Snack. In some rare cases this bundling process might fail, usually because it tries to refer React Native internals like these files. Let us know if you run into Snackager failures.
If Snack assets aren't loading, that's because those assets are loaded from Snack's own CDN. React Native doesn't know about this CDN, it needs to be registered before you can use Snack assets.
This snippet should be placed in the index.js
file. If you already have a custom source transformer, you have to add it to your own script instead.
// Allow assets to be resolved from the Snack CDN
import { registerSnackAssetSourceTransformer } from 'snack-runtime';
registerSnackAssetSourceTransformer();
// Or, add the Snack CDN as one of other strategies to resolve assets
import { resolveSnackAssetSource } from 'snack-runtime';
import { setCustomSourceTransformer } from 'react-native/Libraries/Image/resolveAssetSource';
setCustomSourceTransformer((resolver) => {
const snackAsset = resolveSnackAssetSource(resolver.asset);
if (snackAsset) {
return snackAsset;
}
// ... custom resolve logic
return resolver.defaultAsset();
});
with ❤️ Expo