Snack Custom Runtime

Experimental project demonstrating Snack in custom native runtimes

App  —  Start it  —  Customize it  —  Examples  —  Caveats  —  Common Errors


📁 App Structure

This demo app uses expo-dev-clients and contains the Snack Runtime to load and render Snacks.

🚀 How to start it

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 🤷

Running on Android

  • $ expo run:android --device - Builds the app on an emulator or real device

    adb 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.

Running on iOS

  • $ 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

👷 How to customize it

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.

🍿 Snack examples

Here are some Snacks that you can use as inspiration, and load it in the client.

⚠️ Caveats

Missing native libraries

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 and Snackager

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.

❌ Common Errors

Snack assets aren't being resolved

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