Convex 1.1 is the post-1.0 release with new features:

  • Conditionally run useQuery with "skip"
  • Upgraded esbuild supporting new TypeScript syntax
  • Warn on unawaited promises
  • New JavaScript runtime builtins
  • Global function runner in the dashboard

This release changes the generated code so you’ll need run codegen to complete the upgrade. Running the standard file-watching dev command npx convex dev will take care of this or you can update generated code manually with npx convex codegen.

Conditionally run useQuery with "skip"

With React it can be tricky to dynamically invoke a hook because hooks cannot be placed inside conditionals or after early returns:

let data;
if (param) {
  // ERROR! React Hook "useQuery" is called conditionally. React Hooks must
  // be called in the exact same order in every component render.
  data = useQuery(api.functions.read, { param });
}

Now you can pass the special string value "skip" in place of the arguments object to a query to avoid running it. This return value will be undefined, just like it would be if the result were still loading.

const data = useQuery(
  api.functions.read,
  param !== null ? { param } : "skip"
);

Read the docs for more: https://docs.convex.dev/client/react#skipping-queries

Upgraded esbuild supporting new TypeScript syntax

The Convex CLI uses esbuild to bundle Convex functions. Since esbuild bundles TypeScript code, you can use any version of TypeScript you like (we recommend 5.0.3 or above) with Convex but the actual compilation of TypeScript will be done by esbuild.

Upgrading esbuild to 0.17.5 allows Convex functions written in TypeScript to use new TypeScript syntax like const type parameters. While it’s possible to use a custom esbuild version via npm overrides, we’ll continue to keep the default version of esbuild installed by Convex up to date to support the latest TypeScript syntax.

Warn on unawaited promises

It’s important to use await with async functions like database reads and writes in Convex functions. The no-floating-promises ESLint rule helps detect unawaited, “floating” promises.

Convex now logs a warning in the dashboard logs at runtime when a promise has not been resolved by the time the Convex function finishes executing. Currently the Convex JavaScript execution engine runs these unawaited promises in some circumstances, a behavior which is difficult to reason about. In the future this behavior may be simpler: the runtime may not run any unawaited promises at all.

Convex JavaScript runtime improvements

We’re always improving the Convex JavaScript runtime to allow more npm modules to work without needing to resort to using Node.js runtime via the "use node"; directive. Support for streaming APIs and the most common crypto APIs in particular should enable use of more npm packages.

Let us know if a dependency you need doesn’t work in the Convex runtime — some packages are fundamentally written to use Node.js APIs, but most shouldn’t require Node.js and hearing from you helps us prioritize which to add support for next.

Global function runner in the dashboard

The function runner is now available from any pane: watch data change as you run a mutation or watch a query update live as you modify data.

There are many other changes in the dashboard:

  • Smoother, more spreadsheet-like interaction when viewing and editing data
  • Ability to add multiple documents at once
  • Team-level usage graphs
  • View other team members’ dev deployments by URL
  • Show logs for a specific subset of functions
  • Cancel all scheduled jobs

Thanks to the community for so much excitement about the 1.0 release!