Elim
Elim8mo ago

Exclude a folder from automatic API generation in Convex?

I would like to exclude a specific folder from automatic API generation. Specifically, I want to have a ./helpers/feature folders to store helper functions that should not be treated as API functions. However, since these helpers are used only by convex, I would like to keep them inside rather than moving them outside convex/. Is there an official way to configure this, like a .convexignore file or some setting in convex.json? It seems like there is a "exclude" array in convex.json but putting my folder path inside the array is not working.
12 Replies
Convex Bot
Convex Bot8mo ago
Thanks for posting in <#1088161997662724167>. Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.) - Use search.convex.dev to search Docs, Stack, and Discord all at once. - Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI. - Avoid tagging staff unless specifically instructed. Thank you!
erquhart
erquhart8mo ago
You can include your helper function files in the convex directory without any undesirable side effects as far as I know. What are you seeing?
OuiOuiCroissant
OuiOuiCroissant2mo ago
same issue here, causes annoying ciruclar deps. I dont want to have to annotate each type, ignoring documents from being dumped in the fullApi during codegen would solve it and save on ts inference on files that are ignored anyways by the FilterApi Would be great to do the filtering at gen time, instead of a type level helper. checking whether a mutation/query/action is exported in a module should be fairly straighforward.
erquhart
erquhart2mo ago
If you have a file in your convex folder that does not export any convex functions, it won't be present in the types for api or internal. Can you help me understand the problem you're seeing, in context? eg., an example scenario where there's a problem
OuiOuiCroissant
OuiOuiCroissant2mo ago
Exlusion of api or internal doesn’t exclude type imports from the files. The way codegen works, all files and directories are crawled, imported in the fullApi, then filtered out with typescript. This is silly, as it both worsens ts performance and leads to annoying circular imports. Eg: If my helper function in a helper “helpers/foo” calls Internal.something in a scheduled function, it will lead to a circular dependency. Since the file depends on the _generated/api file, which imports “helpers/foo” as well, with absolutely no benefit
erquhart
erquhart2mo ago
Ah I see. I do know there are some non-ideal things in type generation and type performance. Are you seeing significant impact to your development or deployment experience in practice? Trying to quantify impact.
OuiOuiCroissant
OuiOuiCroissant2mo ago
Yes it is fairly annoying. Every single helper method that uses a scheduled function needs explicit annotations. Not the end of the world, but with a simple convexignore that is fixed and less type checking draining ts performance Most of my code is in helpers that shouldnt be crawled
erquhart
erquhart2mo ago
Every single helper method that uses a scheduled function needs explicit annotations
This is the part I need to understand, can you give me an example? I haven't had to do this when using scheduled functions
OuiOuiCroissant
OuiOuiCroissant2mo ago
Sure, here’s a minimal example of what I mean:
// File: jobs/processMessage.ts
import { internalMutation } from "../_generated/server";
import { v } from "convex/values";

export const processMessage = internalMutation({
args: { message: v.string() },
handler: async (ctx, args) => {
console.log("Processing:", args.message);
},
});
// File: jobs/processMessage.ts
import { internalMutation } from "../_generated/server";
import { v } from "convex/values";

export const processMessage = internalMutation({
args: { message: v.string() },
handler: async (ctx, args) => {
console.log("Processing:", args.message);
},
});
// File: helpers/foo.ts
// This helper imports from the generated API
import { internal } from "../_generated/api";

export async function helperCallScheduledJob(ctx: …, message: string) {
// Calls a scheduled internal function
await ctx.scheduler.runAfter(
1000,
internal.jobs.processMessage,
{ message }
);
}
// File: helpers/foo.ts
// This helper imports from the generated API
import { internal } from "../_generated/api";

export async function helperCallScheduledJob(ctx: …, message: string) {
// Calls a scheduled internal function
await ctx.scheduler.runAfter(
1000,
internal.jobs.processMessage,
{ message }
);
}
Where the circular dependency comes from • helpers/foo.ts imports from ../_generated/api. • The generated API (_generated/api) is built by crawling every file, which means it imports helpers/foo.ts as part of fullApi. • This creates a cycle: helpers/foo.ts → _generated/api → helpers/foo.ts Why it’s a problem Because of that cycle, TypeScript type inference breaks down. I end up having to explicitly annotate helper methods that use scheduled functions, since TS can’t resolve the types through the circular import chain. If helper files could be excluded from codegen crawling (e.g. via .convexignore), the cycle would disappear and inference would just work.
OuiOuiCroissant
OuiOuiCroissant2mo ago
GitHub
Add ignore package and implement .convexignore support in bundler b...
Added the ignore package to dependencies. Implemented loading and processing of .convexignore files in the bundler to skip specified files during the build process. Updated entry point logic to res...
OuiOuiCroissant
OuiOuiCroissant2mo ago
fixes the issue in my repo and significantly reduces the size of my fullApi fullApi goes from 163 LOC to 59 in a fairly minimal project Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.ts(7024) issue no longer a thing @erquhart any chance to expedite the review process?
erquhart
erquhart2mo ago
The team would have to decide if this approach is what's desired. The helpers file shouldn't be affecting things that way - I do understand you're saying the fix addressed it. But I need a clear "Expected" vs "Actual". I don't see where you need a type and don't have one, if that makes sense. I have helpers and scheduled functions all over the place in Convex projects and haven't had an issue with inference because of it, so maybe there's some aspect of your scenario that I'm not understanding. But yeah, clear "Expected" vs "Actual", and what types you're getting vs expecting, maybe screenshot?

Did you find this page helpful?