Skip to content

feat: add customize callback to createApp, remove autoStart#280

Draft
MarioCadenas wants to merge 1 commit intomainfrom
feat/customize-callback
Draft

feat: add customize callback to createApp, remove autoStart#280
MarioCadenas wants to merge 1 commit intomainfrom
feat/customize-callback

Conversation

@MarioCadenas
Copy link
Copy Markdown
Collaborator

@MarioCadenas MarioCadenas commented Apr 16, 2026

Summary

  • Adds a customize callback option to createApp that runs after plugin setup but before the server starts, replacing the autoStart: false + .extend() + .start() ceremony
  • Server start is now orchestrated by createApp (looks up "server" plugin by name), making autoStart and manual start() unnecessary
  • Removes autoStart from public API (ServerConfig, DEFAULT_CONFIG, manifest) and start() from server exports

Before / After

Before:

const appkit = await createApp({
  plugins: [server({ autoStart: false }), analytics({})],
});
appkit.server.extend((app) => {
  app.get("/custom", (_req, res) => res.json({ ok: true }));
});
await appkit.server.start();

After:

await createApp({
  plugins: [server(), analytics({})],
  customize(appkit) {
    appkit.server.extend((app) => {
      app.get("/custom", (_req, res) => res.json({ ok: true }));
    });
  },
});

Test plan

  • All existing tests updated and passing (1560/1560)
  • New integration test: async customize callback runs before server starts
  • New integration test: customize callback works without server plugin
  • Typecheck passes
  • Build passes
  • Biome lint passes on changed files

Replace the post-await extend/start ceremony with a declarative
`customize` callback on createApp config. The callback runs after
plugin setup but before the server starts, giving access to the
full appkit handle for registering custom routes or async setup.

- Add `customize` option to createApp config
- Server start is now orchestrated by createApp (lookup by name)
- Remove `autoStart` from public API, ServerConfig, and manifest
- Remove `start()` from server plugin exports
- Remove autoStart guards from extend() and getServer()
- Remove ServerError.autoStartConflict()
- Migrate dev-playground, template, and all tests

Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
@MarioCadenas MarioCadenas force-pushed the feat/customize-callback branch from d49f16d to 33e0b86 Compare April 16, 2026 10:43
@atilafassina
Copy link
Copy Markdown
Contributor

I think this is a step in the right direction and we should have this ASAP.
We did a quick search on other server frameworks out there and owning the lifecycle of plugins simplifies things a lot in orchestrating functionality and avoiding race conditions. Removing the autoStart config is just a user-facing bonus of having a more reliable architecture beneath it.

That being said, as we talked on Slack (just surfacing this here), the API name could change. customize doesn't really translates to the user only the intent, not what it's doing (and more importantly when), makes it less intuitive and discoverable. customize should be split in pre() and post() hooks, running respectively before and after plugin instantiation.

The use case we need to cover immediately is pre(), so I think just renaming this here and shipping this incrementally would be great already, we cross the post() bridge when we get there perhaps - who knows, maybe we need more hooks in the future as our typegen/compiler story evolves.

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