npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

alchemy-convex

v0.0.2

Published

Effect-native Convex project resources for Alchemy v2

Downloads

42

Readme

Convex

An Alchemy provider for creating Convex projects and deploying production, development, and preview environments.

alchemy-convex manages project and deployment lifecycles, environment variables, and authentication. The official Convex CLI continues to handle typechecking, code generation, bundling, and code deployment.

Installation

bun add alchemy-convex "alchemy@next" convex "effect@beta" \
  "@effect/platform-bun@beta" "@effect/platform-node@beta"

Authentication

Configure a Convex credential through Alchemy:

bun alchemy login --configure

The provider supports three authentication methods:

  • Environment Variable reads CONVEX_ACCESS_TOKEN and is selected automatically when CI=1.
  • OAuth opens Convex in the browser and stores an application token in the active Alchemy profile.
  • Access Token securely prompts for a Convex team access token and stores it in ~/.alchemy/credentials/<profile>/.

Create team access tokens from the Convex Team Settings access-token page. A token has the permissions of the member who created it, so use a dedicated service account for automation.

OAuth uses the provider's registered Convex application and the localhost redirect URI http://localhost:9976/auth/callback; no client credentials are required.

The provider never stores CONVEX_DEPLOY_KEY. During reconciliation it obtains a deployment-scoped key from Convex. Team-token keys expire after one hour and are revoked when the CLI exits. OAuth deployment credentials remain backed by the OAuth grant. Neither deployment credential is written to resource properties, outputs, Alchemy state, profiles, or CLI arguments.

Creating a Stack

Register the Convex providers, create a project, and deploy it:

import * as Alchemy from "alchemy";
import * as Convex from "alchemy-convex";
import * as Effect from "effect/Effect";

export default Alchemy.Stack(
  "MyApp",
  {
    providers: Convex.providers(),
    state: Alchemy.localState(),
  },
  Effect.gen(function* () {
    const project = yield* Convex.Project("Backend");

    const deployment = yield* Convex.Deployment("BackendDeployment", {
      project,
      env: {
        APP_ENV: "production",
      },
    });

    return {
      convexUrl: deployment.url,
      convexHttpActionsUrl: deployment.httpActionsUrl,
    };
  }),
);

Deploy the stack:

bun alchemy deploy

Project

Source: src/Project.ts

A Convex project that can be created, adopted, updated, and removed through an Alchemy stack. Deploy code to the project with a child Deployment resource.

Creating a Project

Create a project with a generated physical name:

const project = yield* Convex.Project("Backend");

Alchemy derives the name from the stack, stage, and resource ID. Set name to use a specific Convex project name:

const project = yield* Convex.Project("Backend", {
  name: "my-backend",
});

Configuring the Project Root

rootDir identifies the directory containing the project's package.json and Convex configuration. It defaults to ".", the stack's working directory.

const project = yield* Convex.Project("Backend", {
  rootDir: "./apps/backend",
});

Each child deployment runs the Convex CLI installed in this directory. No global Convex CLI installation is required. Override the executable when registering providers:

providers: Convex.providers({
  binary: "/path/to/convex",
});

Customizing Source Hashing

Alchemy hashes the project source and skips deployment when both the resource properties and source are unchanged. Secrets, dependencies, build outputs, Alchemy state, and convex/_generated are excluded by default.

Use source.include and source.exclude to customize hashing in a monorepo:

const project = yield* Convex.Project("Backend", {
  rootDir: "./apps/backend",
  source: {
    include: ["convex/**", "packages/domain/**", "package.json", "bun.lock"],
    exclude: ["packages/domain/test/**"],
  },
});

Deployment

Source: src/Deployment.ts

A production, development, or preview deployment within a Project. It reconciles environment variables before invoking the project's local Convex CLI.

Deploying to Production

reference defaults to "production":

const deployment = yield* Convex.Deployment("BackendDeployment", {
  project,
});

deployment.url;
deployment.httpActionsUrl;

The default production deployment is attached automatically because Convex creates it with the parent project.

Creating Development and Preview Deployments

Use a stable dev/<name> or preview/<name> reference:

const development = yield* Convex.Deployment("AgentDeployment", {
  project,
  reference: "dev/agent-1",
});

const preview = yield* Convex.Deployment("PullRequest", {
  project,
  reference: "preview/pr-123",
  expiresAt: "2030-01-01T00:00:00Z",
});

expiresAt is only valid for preview deployments and accepts an ISO timestamp or Unix milliseconds. Convex's generated physical deployment name is available as deployment.name.

Configuring a Deployment

Control Convex CLI behavior for an individual deployment:

const deployment = yield* Convex.Deployment("BackendDeployment", {
  project,
  typecheck: "enable",
  codegen: true,
  message: "Deploy from Alchemy",
});

typecheck accepts "enable", "try", or "disable" and defaults to "try". codegen defaults to true. Set alwaysDeploy: true to run the CLI even when the resource properties and source hash are unchanged.

Setting Environment Variables

Pass literal values or outputs from other Alchemy resources through env:

const web = yield* Cloudflare.Worker("Web", {
  main: "./src/worker.ts",
});

const deployment = yield* Convex.Deployment("BackendDeployment", {
  project,
  env: {
    APP_ENV: "production",
    SITE_URL: web.url,
  },
});

Alchemy resolves nested outputs before reconciliation. Variables removed from env are removed from Convex on the next deployment.

Adopting Existing Resources

Alchemy requires explicit adoption when a named project or a development or preview reference already exists outside the stack:

import { adopt } from "alchemy/AdoptPolicy";

const project = yield* Convex.Project("Backend", {
  name: "existing-project",
  rootDir: "./apps/backend",
}).pipe(adopt());

const deployment = yield* Convex.Deployment("ExistingPreview", {
  project,
  reference: "preview/pr-123",
}).pipe(adopt());

You can also deploy with the --adopt CLI flag.

Removal Behavior

Convex projects and production deployments are retained by default when the Alchemy stack is destroyed. This protects the production deployment, including its data and files, from being deleted by ordinary stack cleanup. Development and preview deployments are still deleted by default.

To intentionally delete a project and all of its deployments, opt the project into the destroy removal policy. Convex deletes the production deployment as part of deleting its parent project:

import { destroy } from "alchemy/RemovalPolicy";

const project = yield* Convex.Project("Backend", {
  rootDir: "./apps/backend",
}).pipe(destroy());

Use retain() when a development or preview deployment should also survive stack removal:

import { retain } from "alchemy/RemovalPolicy";

const deployment = yield* Convex.Deployment("Preview", {
  project,
  reference: "preview/pr-123",
}).pipe(retain());

Runtime Model

Deployment uses Alchemy's Platform API with a Convex-specific runtime context. Alchemy resolves outputs nested in deployment properties before passing the source tree and environment to the Convex CLI.

The provider deploys standard Convex functions. It does not translate Effect HTTP handlers into Convex queries, mutations, or actions.

Development

bun install
bun run format:check
bun run lint
bun run check
bun run test
bun run build

Provider tests inject ConvexCli and ConvexManagementApi layers, exercising Alchemy's create, no-op, update, and destroy lifecycle without accessing a real Convex deployment or local profile.