Skip to content

Conversation

@franknoirot
Copy link
Contributor

Truly completes #8885 by finishing the last step in the migration. Instead of directly importing singleton objects from @src/lib/singletons.ts, we now provide them to the app in one place in index.tsx on a React Context provider, then access them through a new useSingletons hook.

I whipped this up today by making the breaking changes in singletons.ts and index.tsx, doing one example of some tsc fixes in the first commit, then prompting Codex to monkey-see-monkeybot-do with the loop. I cleaned up some of it's output but good lord it saved me a lot of keystrokes.

Truth be told I'm not positive this is very helpful, so consider it more of a discussion PR. It seems like a smell to me that we can import from the singletons file all over React, but is it all that bad? And maybe a more fair question is this: is using a useContext hook all that much better? Would the real improvement be to pass down the values needed wherever necessary, and not these often big singleton objects? Just some thoughts; I don't want this to get in the way of anyone else's work.

@vercel
Copy link

vercel bot commented Jan 17, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
modeling-app Ready Ready Preview, Comment Jan 18, 2026 6:06am

Request Review

Copy link
Contributor Author

@franknoirot franknoirot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some initial self-review for us to discuss!

Comment on lines 455 to 457
export const singletons = buildSingletons()
export const SingletonsContext = React.createContext(singletons)
export const useSingletons = () => React.useContext(SingletonsContext)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important change number one: no more direct exports, only these 3 exports are available (plus one type def up top but who's counting).

src/index.tsx Outdated
iconTheme: {
primary: 'oklch(89% 0.16 143.4deg)',
secondary: 'oklch(48.62% 0.1654 142.5deg)',
<SingletonsContext.Provider value={singletons}>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important change number two: providing the singletons as a single context object at the top of the component tree.

return useMemo(() => {
return { value, onClick: onCodeNotificationClick, title: undefined }
}, [value])
export const useDefaultAreaLibrary = () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex got a little refactor happy converting config objects like this on into hooks to make it possible to call useSingletons from here. I'm not sure how I feel about that pattern, but it does work the same at least in my user testing.

@franknoirot franknoirot force-pushed the franknoirot/8885/inject-singletons-into-React branch from 9fac254 to 2b86b66 Compare January 17, 2026 16:06
@franknoirot
Copy link
Contributor Author

You know what, I actually think that it would be more prudent to wrap the singletons into a Class call app. Then we can start defining methods and such on the class. I think I will still allow this hook and the concepts of "singletons" to float around, but they'll be getters on a class. We should be moving in the direction of a robust app class that learns from the designs of the likes of Obsidian and tldraw

@franknoirot
Copy link
Contributor Author

You know what, I actually think that it would be more prudent to wrap the singletons into a Class call app.

Okay now I've done that. It's worth noting that what I've done so far does not pass the app into the...app yet, only the singletons. But I like this because it

  1. Gives us a place to put high-level methods onto the app
  2. Still provides a React-friendly interface through the singletons, to give us a familiar setup for the time being

Some things I don't like about this approach:

  1. Because I was afraid of having to redo my work changing all the imports, I made the app be instantiated once right next to it's definition, the export const app = new App(). This is bad for a number of reasons, one of which is you have to instantiate an App class to import anything, just very impure.

Blah, I'm gonna try to do away with that real quick.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants