Skip to content

Instantly share code, notes, and snippets.

View EvanBacon's full-sized avatar
🥓
Markdown developer

Evan Bacon EvanBacon

🥓
Markdown developer
View GitHub Profile
@EvanBacon
EvanBacon / CLAUDE.md
Created July 22, 2025 16:43
Expo Router CLAUDE.md file.

Architecture

  • Website: Expo Router website with Tailwind.
  • Native app: Expo Router app with CNG.
  • Backend: Expo API routes WinterTC-compliant. Routes are in src/app/api/ directory. API routes use +api.ts suffix (chat+api.ts).
  • Secrets: Use .env files and API routes for secret management. Never use EXPO_PUBLIC_ prefix for sensitive data.

Code Style

  • Use TypeScript whenever possible.
@EvanBacon
EvanBacon / _layout.tsx
Created April 23, 2025 22:23
Loading fonts with React Suspense in Expo
import { SplashScreen } from "expo-router";
import React, { Suspense, useEffect } from "react";
import { Text, View } from "react-native";
import * as Font from "expo-font";
SplashScreen.preventAutoHideAsync();
function SplashFallback() {
@EvanBacon
EvanBacon / local-storage-polyfill.ts
Last active November 28, 2024 03:57
Polyfill localStorage in Expo SDK 52
import { Storage } from "expo-sqlite/kv-store";
// localStorage polyfill. Life's too short to not have some storage API.
if (typeof localStorage === "undefined") {
class StoragePolyfill {
/**
* Returns the number of key/value pairs.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Storage/length)
*/
@EvanBacon
EvanBacon / skeleton.tsx
Created October 23, 2024 23:38
Animated skeleton component with Expo SDK 52
"use client";
import React from "react";
import { View, StyleSheet, Animated, Easing, ViewStyle } from "react-native";
const BASE_COLORS = {
dark: { primary: "rgb(17, 17, 17)", secondary: "rgb(51, 51, 51)" },
light: {
primary: "rgb(250, 250, 250)",
secondary: "rgb(205, 205, 205)",
@EvanBacon
EvanBacon / dismiss-completed-gh-notifications.js
Last active July 15, 2023 05:08
Select and dismiss GH notifications for merged and closed issues/PRs. https://twitter.com/Baconbrix/status/1679925775162548224?s=20
[...document.querySelectorAll('.notifications-list-item:has(.octicon-git-merge)'), ...document.querySelectorAll('.notifications-list-item:has(.octicon-skip)'), ...document.querySelectorAll('.notifications-list-item:has(.octicon-issue-closed)'), ...document.querySelectorAll('.notifications-list-item:has(.octicon-discussion-closed)'), ...document.querySelectorAll('.notifications-list-item:has(.octicon-git-pull-request-closed)')].forEach(el => el.querySelector('input').click()); setTimeout(() => document.querySelector('button[type="submit"][role="menuitem"][title="Done"].btn').click(), 200)
@EvanBacon
EvanBacon / expo-vscode-settings.json
Created February 14, 2023 18:33
Expo file nesting patterns. Ensure all related extensions are nested inside of the default file.
{
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.patterns": {
"*.js": "${capture}.js.map, ${capture}.d.ts, ${capture}.d.ts.map",
"*.ts": "$(capture).test.ts, $(capture).test.tsx, $(capture).test.node.ts, $(capture).test.node.tsx, $(capture).test.native.ts, $(capture).test.native.tsx, $(capture).test.ios.ts, $(capture).test.ios.tsx, $(capture).test.web.ts, $(capture).test.web.tsx, $(capture).test.android.ts, $(capture).test.android.tsx, ${capture}.native.tsx, ${capture}.ios.tsx, ${capture}.android.tsx, ${capture}.web.tsx, ${capture}.native.ts, ${capture}.ios.ts, ${capture}.android.ts, ${capture}.web.ts, ${capture}.native.js, ${capture}.ios.js, ${capture}.android.js, ${capture}.web.js, ${capture}.native.jsx, ${capture}.ios.jsx, ${capture}.android.jsx, ${capture}.web.jsx",
"*.tsx": "$(capture).test.ts, $(capture).test.tsx, $(capture).test.node.ts, $(capture).test.node.tsx, $(capture).test.native.ts, $(capture).test.native.tsx, $(capture).test.ios.ts, $(capture).test.ios.tsx, $(captur
@EvanBacon
EvanBacon / withVideoImportSupport.js
Created October 13, 2022 19:26
An Expo Config Plugin that enables opening any video file type in your iOS app
// https://gist.github.com/EvanBacon/98858a341e2da209587455bbad465931
const includesEverything = {
CFBundleDocumentTypes: [
{
CFBundleTypeExtensions: ["*"],
CFBundleTypeName: "All files",
CFBundleTypeOSTypes: ["*"],
},
{
CFBundleTypeExtensions: ["mov"],
@EvanBacon
EvanBacon / metro-transformer.js
Created December 22, 2021 20:31
Using Realm with Expo Metro config "Exotic" bundling.
const { createExoticTransformer } = require("@expo/metro-config/transformer");
module.exports = createExoticTransformer({
// Add realm packages to the list of modules to transpile locally.
transpileModules: ["@realm/", "realm"],
});
@EvanBacon
EvanBacon / RootViewBackgroundColor.tsx
Created December 10, 2021 21:44
A stack based Expo component for setting the background color of the root view. Useful for changing the background color on certain screens or inside of native modals. Updates based on Appearance and AppState.
import * as SystemUI from 'expo-system-ui';
import * as React from 'react';
import { Appearance, AppState, AppStateStatus, ColorSchemeName, ColorValue } from 'react-native';
type ThemedColorValue = { light: ColorValue, dark: ColorValue };
type Props = { backgroundColor: ColorValue | ThemedColorValue }
const propsStack: Props[] = [];
@EvanBacon
EvanBacon / Info.plist.json
Last active May 15, 2023 08:53
[Expo Config Plugins] JSON version of CFBundleDocumentTypes, UTExportedTypeDeclarations, UTImportedTypeDeclarations from VLC app Info.plist -- good for importing different file formats into your app
{
"CFBundleDocumentTypes": [
{
"CFBundleTypeName": "Folder",
"CFBundleTypeRole": "Viewer",
"LSItemContentTypes": [
"public.folder"
]
},
{