Summary
The Web target does not start. npm run web serves a blank page and throws before the first screen renders:
TypeError: (0 , _expoSqlite.openDatabaseSync) is not a function
at Object.get [as ./_layout.tsx]
at metroContext
at loadRoute
at getDirectoryTree
at getRoutes
at ContextNavigator
React then reports An error occurred in the <ContextNavigator> component, and nothing mounts.
Observed on e2d5e05 in Chrome against npx expo start --web (port 8081, bundle built successfully — this is a runtime failure, not a bundling one).
The chain
Three facts, each verified:
src/database/index.ts:6 calls openDatabaseSync("snowlog.db", …) at module scope, so merely importing the module opens the database.
src/database/index.ts has no .web.ts companion. Every repository under src/database/repositories/ has one; the module that creates the Drizzle singleton does not.
expo-sqlite's web build does not provide that export. node_modules/expo-sqlite/build/ExpoSQLite.web.js contains no openDatabaseSync — grep returns nothing, while the native build has it.
The import that pulls it in is src/app/_layout.tsx:20 — import { db } from "@/database", needed for useMigrations.
Why _layout.web.tsx does not save us
src/app/_layout.web.tsx exists specifically to avoid this. Its header comment says so:
Web用ルートレイアウト
expo-sqlite / Drizzle はブラウザ非対応のため、DBマイグレーションをスキップする
It skips migrations and never imports @/database. But the stack frame reads Object.get [as ./_layout.tsx] — Expo Router's require.context route tree loaded the native _layout.tsx, so the web variant never ran.
This is the part worth confirming before choosing a fix: Metro's platform resolution applies to import specifiers, so @/database/repositories/videoRepository does correctly become videoRepository.web.ts inside whichever layout loads. It is the route-file lookup itself that appears not to prefer the .web.tsx variant. Whether that is an Expo Router v4 behaviour, a config gap, or something about _layout specifically, I did not determine.
Why this matters more than it looks
.memory/wiring.md and SnowLog.md §12.3 both describe Web as a working preview surface for layout checks, and the repository maintains 15 native/.web module pairs to support it. #71 and #74 were both filed and fixed to keep those shims honest.
If the app cannot boot on Web, none of that is reachable, and the acceptance criterion in #74 — "bulk delete, bulk favourite, custom-tag delete and technique reorder all work on Web without a TypeError" — cannot be exercised at all. The parity work still stands on its own (the exports exist and a test now enforces them), but it has not been, and currently cannot be, confirmed by clicking.
Why this needs a decision rather than a patch
There are three defensible responses and they differ in scope:
- Add
src/database/index.web.ts — a stub exporting a db that throws or no-ops. Smallest change; makes the native _layout.tsx survive on Web. But it papers over the fact that the wrong layout is loading, and the native layout would then run its whole startup sequence (migrations, seeding, thumbnail migration, orphan cleanup) against a fake database.
- Make Expo Router pick up
_layout.web.tsx — the intended design. Needs a diagnosis I did not finish, and may not be supported for _layout files in Expo Router v4.
- Drop the Web target — delete the 15 shims, the four
.web.tsx screens, and the parity test, and say plainly in SnowLog.md that Web is unsupported. That removes a standing maintenance cost for a surface that is currently broken and, by the repo's own description, only ever served layout previews.
Option 3 is a product call. Options 1 and 2 differ in how much they actually fix. Not choosing on the maintainer's behalf.
How to reproduce
Open http://localhost:8081, then read the browser console. The page is blank; the exception above is the first entry after the bundle loads.
Acceptance criteria
Related
Summary
The Web target does not start.
npm run webserves a blank page and throws before the first screen renders:React then reports
An error occurred in the <ContextNavigator> component, and nothing mounts.Observed on
e2d5e05in Chrome againstnpx expo start --web(port 8081, bundle built successfully — this is a runtime failure, not a bundling one).The chain
Three facts, each verified:
src/database/index.ts:6callsopenDatabaseSync("snowlog.db", …)at module scope, so merely importing the module opens the database.src/database/index.tshas no.web.tscompanion. Every repository undersrc/database/repositories/has one; the module that creates the Drizzle singleton does not.expo-sqlite's web build does not provide that export.node_modules/expo-sqlite/build/ExpoSQLite.web.jscontains noopenDatabaseSync— grep returns nothing, while the native build has it.The import that pulls it in is
src/app/_layout.tsx:20—import { db } from "@/database", needed foruseMigrations.Why
_layout.web.tsxdoes not save ussrc/app/_layout.web.tsxexists specifically to avoid this. Its header comment says so:It skips migrations and never imports
@/database. But the stack frame readsObject.get [as ./_layout.tsx]— Expo Router'srequire.contextroute tree loaded the native_layout.tsx, so the web variant never ran.This is the part worth confirming before choosing a fix: Metro's platform resolution applies to
importspecifiers, so@/database/repositories/videoRepositorydoes correctly becomevideoRepository.web.tsinside whichever layout loads. It is the route-file lookup itself that appears not to prefer the.web.tsxvariant. Whether that is an Expo Router v4 behaviour, a config gap, or something about_layoutspecifically, I did not determine.Why this matters more than it looks
.memory/wiring.mdandSnowLog.md§12.3 both describe Web as a working preview surface for layout checks, and the repository maintains 15 native/.webmodule pairs to support it. #71 and #74 were both filed and fixed to keep those shims honest.If the app cannot boot on Web, none of that is reachable, and the acceptance criterion in #74 — "bulk delete, bulk favourite, custom-tag delete and technique reorder all work on Web without a
TypeError" — cannot be exercised at all. The parity work still stands on its own (the exports exist and a test now enforces them), but it has not been, and currently cannot be, confirmed by clicking.Why this needs a decision rather than a patch
There are three defensible responses and they differ in scope:
src/database/index.web.ts— a stub exporting adbthat throws or no-ops. Smallest change; makes the native_layout.tsxsurvive on Web. But it papers over the fact that the wrong layout is loading, and the native layout would then run its whole startup sequence (migrations, seeding, thumbnail migration, orphan cleanup) against a fake database._layout.web.tsx— the intended design. Needs a diagnosis I did not finish, and may not be supported for_layoutfiles in Expo Router v4..web.tsxscreens, and the parity test, and say plainly inSnowLog.mdthat Web is unsupported. That removes a standing maintenance cost for a surface that is currently broken and, by the repo's own description, only ever served layout previews.Option 3 is a product call. Options 1 and 2 differ in how much they actually fix. Not choosing on the maintainer's behalf.
How to reproduce
Open
http://localhost:8081, then read the browser console. The page is blank; the exception above is the first entry after the bundle loads.Acceptance criteria
npm run webrenders the app, orSnowLog.mdand.memory/wiring.mdstate that Web is unsupported and the shim infrastructure is removed.TypeError.Related