When pushing convex deploy from node backend and react frontend functions get overwritten
Does anyone know a solution? My react functions are overwrriting my backend node functions and vice versa.
67 Replies
Not sure what you mean here,
convex deploy
only pushes the code in your /convex
directory to Convex - can you share a little more about what's happening?Hi okay so on ymy
frontned reac i have the method getUsers
on my backend i have createPM and createAnalayst
when i deploy the backend only those 2 from the backend show up, and then i get an error that i havent deployed
on my frontend, and vice versa on my backend
"when i deploy the backend only those 2 from the backend show up" - show up where
on the functions tab
in the convex dashboard
so you have other functions that aren't showing up?

This is from my frontend convex deploy
Convex deploy is backend only

okay
what is frontend
Generally a react app of some sort (next, etc), deployed on a host like Netlify or Vercel. But could be anything, event html with a script tag loading Convex, hosted on a server in your closet
sorry as iin
what is the command
to deploy the functions we create on the frontend
Those three functions you mentioned, getUsers, createPM, createAnalyst, those would all be backend functions
What is your frontend using, plain react or a framework like Next?
plain react
this si ym get users function
on the frontend
import { query } from "./_generated/server";
import { v } from "convex/values";
export const getUsers = query({
args: { member_id: v.string() },
handler: async (ctx, args) => {
const user = await ctx.db
.query("users")
.filter((q) => q.eq(q.field("member_id"), args.member_id)).collect()
// console.log(user)
console.log("query user")
return user;
},
});
Heres how I use it in react
import { create, createStore } from "zustand";
import { api } from "../../convex/_generated/api";
import { convexClient } from "../utils/convex";
export const useUser = create((set) => ({
userData: {},
fetch: async (memeber_id:any) => {
console.log(memeber_id)
try {
const dataConvex = await convexClient.query(api.getUsers.getUsers,{member_id:memeber_id})
if(dataConvex){
set({ userData: dataConvex[0]});
}
} catch (error) {
console.error("Error fetching user data:", error);
}
},
}));
That getUsers function is your backend
The react part is your frontend
What's the path where you have the getUsers function
convex
and what about the other two functions
under the parent folder
those are on a seperate
node server folder
you're going to want to keep them all together
is the separation because you don't want createPM and createAnalayst to be callable from the client?
yes
there is some logic
I want to keepo
isolated
I found a workaround where I just copying the getUsers.ts
into my node backend
but it still deletes
my backend functions
Are you using auth in convex at all
using a
auth provider that is not connected
to
convex
but no nothing integrated with convex
so your createPM function, even if you run it in a separate convex project, will still be exposed to the public web and can be called by anyone - are you already accounting for that
using the internalMutation
oh wait
Oh okay - if you're successfully running internal functions, you don't need to separate the functions at all, internal functions aren't published in your backend
nevermind
that
doesnt work
yeah, has to start from a non-internal function first
is there no way to append new functions to existing ones?
you're going to need auth working in convex
on the convex dashboard
I am using stytch as this is for B2B
There's a doc for connecting any auth provider, custom auth
Custom Auth Integration | Convex Developer Hub
Convex can be integrated with any identity provider supporting the
what would connecting auth do?
So here's the breakdown:
- you're trying to protect certain functions from being accessed directly
- you're attempting to do this by splitting your convex functions into two separate locations
- this won't actually stop those functions from being accessed, and you can't server your convex backend from two different roots (which is why the overwrite is occurring)
- the way to do what you're trying to do is through using internal functions
- internal functions must be called by non-internal functions
- you can't safely publish non-internal functions because your convex functions don't have auth set up
okay makes sense
So you need to:
- set up auth in your convex functions using Stytch and the custom auth guide above
- put all of your convex functions in the convex directory
- make the protected functions internal (although you'll likely find authentication makes this unecessary)
If you do make some functions internal, which is very common, you'll need authenticated non-internal functions that can then schedule those functions. But again, for regular crud ops you'll likely just have authenticated non-internal functions, internal functions are often for scheduled operations, background jobs, etc
okay
makes sense
but which convex directory?
I have 2
connected to the same project
You'll generally want to just put everything under
/convex
Functions don't need to be colocated with your node backend to be accessible when publishedokay sure, but like we identified when one of either the backend/frontend
compiles
it overwrites the functions of the other
so you're using convex deploy for your frontend build, and also separately for your backend build, right
yes
are they in separate repos?
yes
Gotcha - I'd recommend just running convex deploy in your frontend repo and housing your functions there
That splits your backend, which isn't great, but keeping the convex functions in your frontend repo gives you access to types in your react code.
is there a workaround?
Are you using Typescript on your frontend
Yes
Is your current intent to try out Convex and maybe start migrating away from the node backend over time
There's a ton of value in having end-to-end types, that's a big part of the value Convex brings to a typescript project - it's trivial to keep your backend and frontend in a single repo.
As far as a workaround, you really want to choose one or the other, either keep all of your backend code in the other repo and not have the types in your frontend (or hack together a cross repo solution to that problem), or keep it all with the frontend, with an eye toward your backend being able to coexist in your frontend repo in the future (and end-to-end types just work).
The thing is this is an enteprise application, so alot of the business logic will have to be distinct
kind of would be a deal breaker
honestly
i am thinking I just seperate all the queries to the backend
Or I may just revert to supabase
probably the first as beyond auth alot of the bsuiness logic needs processing on the backend first
Ah okay - let’s see if the team has any creative ideas here
I am all down for it, really liking convex.
The standard advice here is to have it in a monorepo if it's used by multiple projects. You can use git subtree if you want to use separate repos but share a subdirectory.
If that doesn't suite you, you can have all your functions in the "backend" repo, and lose typesafety with the frontend repo, where you wouldn't have a convex directory, and would just use the generic
anyApi
instead of api
to separate different logical units - e.g. functions only for a certain frontend - you can have subdirectories in your single convex
folder to namespace them
If you truly have very different needs from the frontend & backend - not sharing much data or functions, you can have them as separate projects and call from one to the other with the HTTPClient, having a client to the other server. That won't allow you to get a reactive query of data in another project, however. I hope that makes sense.
I'm currently working on a Components system, where you could develop functionality in namespaced standalone modules, that have their own tables etc. However, they'd still be deployed under a single app.
One thing to realize here is that if you allowed multiple projects to deploy to the same backend, they would both have to have the exact same schema. This is a difference with Convex and other systems - in Convex, your schema always matches your code. In other ORMs, you can have many versions of what you think the database schema is, and none of them may actually match the actual schema at runtime. You can add or drop columns and the running code may just start breaking
As a side note, the biggest repos I've worked in (hundreds of developers, dozens of distinct services and frontends) have always been monorepos. I understand some systems are stuck with separate repos, or have some policy or business need that prohibits them, but keeping shared dependencies in the same repo is the easiest way for me to reason about these things.
However I believe git subtree can serve your needs - developing a frontend against a clone of the full convex directory, and when you want to go to production, you merge your changes into the "main" convex repo, so all prod backend deploys come from a predictable place and don't overwrite each otherInteresting, I’ll check it out
The thing is this app is pretty intensive with slot of json manipulations so I would also separate concerns in that sense on the backend
I wrapped the getUser around my express backend for the time being
an important thing to know is that unlike supabase, convex functions always run on the server
Interesting
down the line do you think there will be support to add functions from distinct repos
Ohw ow found it
ok yeah it seems
i will have to forgo types until i find a proper workaround
JavaScript | Convex Developer Hub
Convex applications can be accessed from Node.js or any JavaScript runtime that
I know this isn’t exactly what you’re asking for, but how useful would it be to be able to export the types to use in other repos, but still have functions in one repo? Eg you could run a command to codegen the api from a backend, or run a cli command in the backend repo to generate a types file you could copy to your clients? Afaict this would be similar to supabase where you have to sync your schema down. You’d still have only one backend repo but you could be running both locally to test, and only push your frontend once the backend deploy happens.
We’re thinking about individually deployable services but it’s not clear how it’d all work given schema validation guarantees mentioned above
This would be perfect
if I could use {anyApi}
and then import the types from my backend
Just implemented anyApi, works like a charm
thanks for the support, was scared I was going to have to pick another provider
Hi guys! Really loving convex so far. But I have a b2b2c app where I need an admin dashboard and a mobile app. They are both share convex functions, but the convex folder is currently deployed on Vercel. I’ve tried for the last two days to setup a monorepo with turbo/next/react native but is a real pain. Is there any other workaround?
Did you take a look at the monorepo example on the get-convex github organization?
Yep I’ve got it working at first but after adding some native dependencies and doing a development build the react native stuff broke up
But that's not a problem id convex. Right?
Nop… but i think I would have to consider something like supabase or just build a basic rest api
The dev experience while developing alongside nextjs was superb 😔😖
@Matias Daloia hey there. you could expose a REST api with convex HTTP actions for the mobile app and keep the rest the same (web, server-side logic)
Yes but i would loose typesafety right ?
@Matias Daloia if you could share a repo with a repro that’d help. We definitely want to support the combined web + mobile use case, with typechecking.
I finally made it work!! It seems it was an issue while using pnpm… I’ve struggled like 2 days but now it’s finally working 💪🏻💪🏻