Organizations vs Projects in Supabase: Move a Project Between Orgs, Audit Dormant Ones, and Build a Small Inventory Board A developer built a small static inventory board that groups Supabase projects by organization and estimates monthly cost from pasted CLI output, while documenting how to transfer a project between organizations and audit dormant ones. Testing on a throwaway setup, the developer found that a transferred project keeps its project reference and that paused projects appear as "INACTIVE" in `supabase projects list --output json`. The board runs entirely in the browser, requiring no server, access token, or stored data. When your Supabase projects start to pile up, three questions come fast: what belongs to the organization and what to the project, how do I move a project, and which ones are dead? I tried all three on a throwaway setup and built a small board that shows the answer on one screen. Everything here is from my run on 2026-10-27, and prices and rules change. How this was made: I wrote this with Claude's help: it drafted, and I ran every step, edited the text, and checked the results. The mistakes are mine. This is a personal learning project, not an official guide, and I don't work for Supabase. The non-technical version of the idea company and offices : https://medium.com/p/f19c78f2ba25 https://medium.com/p/f19c78f2ba25 The code: https://github.com/tomozilla/project-inventory-en-demo https://github.com/tomozilla/project-inventory-en-demo The Billing FAQ says it plainly: an organization holds many projects; each project is a dedicated instance with its own Storage, Auth, Functions and Realtime; each organization has one subscription plan ; and project add-ons compute, PITR, custom domains are set per project but billed through the organization. My own cheat sheet: | | Organization | Project | |---|---|---| | Plan and billing | here | uses the organization's | | Members and roles | here | covered by the organization's | | SSO, audit logs | here | | | Database, Auth, Storage, Functions | | here | | Compute size, backups, PITR | | here | | API keys, URL | | here | Two consequences from the docs: a paid plan applies to every project in that organization, and you cannot mix free and paid projects inside one organization. My free organization has two projects. One is paused. The pricing page says free projects pause after a week of inactivity, so I assume that is why. I did not confirm the reason on screen. Settings like SSO and audit logs live on the organization side, not in a project. I decide by asking what must never be mixed. One docs detail surprised me: the limit of two active free projects is counted across every Owner and Admin of the organization. If another admin already used their allowance, you can't launch another free project there. The docs suggest creating another free organization or changing that member's role. I am the only member of my organization, so I did not reproduce this. Create the target organization at /dashboard/new . Check that the plan says Free - $0/month . Then open the project's Project Settings - General and scroll to Transfer project . The dialog warns about three things: possible downtime when moving from paid to free, permission changes depending on your role in the target, and lost features for example image transformations on a smaller plan. I picked the new organization and confirmed. It took a few seconds, and the project reference stayed the same . Then I moved it back the same way and deleted the temporary organization Organization Settings - General - Delete organization . Deleting asks you to type the organization's slug. I checked the page title first, because it is permanent. What the docs say, which I did not test: You don't have to open every project. The CLI lists them read-only : supabase projects list --output json Each project comes back with ref , name , organization id , region , created at and status . In my run a paused project showed "status": "INACTIVE" . Two limits matter: Before deleting anything, ask the owner. Paused projects are not charged for compute according to the docs, so there is no rush. I turned that into a page: paste the CLI output, and see projects grouped by organization. It is a static page. No server, no project, no access token, and what you paste stays in the browser. Because the output has no plan, you pick it per organization. The estimate counts running projects only: monthly = Math.max 0, active 10 - 10 ; // Micro $10 per running project, minus the $10 included monthly += plan === "pro" ? 25 : 599; // plan fee Run it from the repository root, because the sample button reads ../sample/ : python3 -m http.server 8000 then open http://localhost:8000/app/ node app/test.js 13 checks supabase projects list --output json | pbcopy your own data macOS With the sample, I set organization 1 to free and organization 2 to pro: I also checked that the parser reads my real CLI output 3 projects in 2 organizations . I looked at the counts only and kept the names out of this article and the repo. I decided the page should never go blank silently. A broken paste shows the reason in red, and rows missing ref , name , organization id , status or created at are skipped with a count , not dropped quietly. The page said "1 projects", and the per-organization tables had different column widths. Both fixed. Ideas I haven't tried: a separate file that maps organization ids to names and owners, a diff against the last inventory so only new or newly paused projects show up, and never letting the tool decide that something is safe to delete. Next in this series: how to read your bill.