Deploy a folder or archive
Put an app online straight from a folder on your computer or a .zip or tar archive (.tar, .tar.gz, .tar.bz2, .tar.xz, .tar.zst), with no Git repository. The browser upload, the archive upload, and the one-command CLI way, with size limits and what gets skipped.
Not everything lives in a Git repository. Sometimes the code is a folder on your laptop, a download, or an archive someone sent you. Synq can take that folder or archive, work out what is inside, build it, and give you back a running app. No Git remote needed.
What you need first
- Synq up and running (you can open the panel). If not, start with Installation.
- A folder or an archive with your app in it: a website, an API, anything.
- You do not need Docker or any special files. Synq reads the source and works out the rest (see Build detection).
Three ways in
| Way | Where | Best for |
|---|---|---|
| Folder upload | New Project → Folder in a browser | A project folder on the computer you are using. |
| Archive upload | New Project → Archive | A .zip, .tar, .tar.gz/.tgz, .tar.bz2, .tar.xz or .tar.zst you already have. |
| CLI | synq deploy --folder in a terminal | Repeat deploys of the same folder, and scripts. |
The desktop app shows the same panel, so its Folder tab uploads the folder the same way.
Upload a folder from the browser
A browser cannot read your disk on its own, so you tell Synq what you are deploying, then hand it the folder. It is packed in your browser and uploaded.
Open the Folder tab
Click New Project in the sidebar, then the Folder tab.
Pick your stack
The tab asks What are you deploying? Choose the tile that matches your app, for example Next.js, Vite or Express. The stack sets the build environment Synq prepares.
Drop in your folder
Drag the project folder onto the drop zone, or click to browse for it. Once it is picked, you see a summary with the folder name and how many files it contains. Clear selection starts over; Back to stack selection changes the stack.
Press Continue
Synq packs and uploads the folder (the button shows Packing folder…, then Uploading…) and opens the deploy screen with the detected settings.
Press Deploy
Check the detected framework and commands, add environment variables and a domain, and press Deploy. The build screen streams the logs; when it finishes, you get a link.
What gets uploaded
Only your source. These are left out, because the build recreates them:
- anywhere in the tree:
.git,node_modules,vendor,.next,.nuxt,.svelte-kit,.astro,.output,.vite,.turbo,.cache,.nx,.react-router,.dev-secrets.json; - at the top of the folder only:
dist,buildanddata(the same names deeper down, such assrc/data, are kept).
If everything was skipped you see "That folder looks empty (or everything was ignored). Pick a project
folder." Choose the folder that holds your package.json (or go.mod, Cargo.toml, requirements.txt,
and so on).
Upload an archive
The Archive tab takes a single archive file of your app and treats its contents like an uploaded folder.
Open the Archive tab
Click New Project in the sidebar, then Archive (or open /library#archive). The card is titled
Upload an app archive.
Drop the archive
Drop a .zip, .tar, .tar.gz (.tgz), .tar.bz2 (.tbz2, .tbz), .tar.xz (.txz) or .tar.zst
(.tzst) file on the drop zone, or click to browse. The project name is taken from the file name
(shop-2.3.zip becomes shop-2.3). Choose another file replaces it. 7z and rar archives are not
supported: repack the app as a .zip or .tar.gz first.
Press Continue
Synq uploads the file ("Uploading…"), unpacks it on the server, and opens the deploy screen. From there it is the same as a folder upload: check the detected build and press Deploy.
How the archive is unpacked
- The format is recognized from the file's contents, not only its name.
- Every tar flavor gets the same checks and limits as a
.tar.gz:.tar.bz2and.tar.xzare unpacked with the server'sbzip2andxzprograms (included in the Synq API image), and.tar.zstwith the runtime's built-in zstd. If a native install lacks one of those programs, that format is refused with a message naming the missing program; the other formats keep working. - If everything in the archive sits in one top-level folder (the usual result of zipping a folder, or of GitHub's "Download ZIP"), that folder becomes the app's root. Otherwise the archive's root is used.
- The macOS
__MACOSXfolder is removed, and a stray top-level.DS_Storedoesn't stop a single wrapping folder from being used as the app root. - Unlike a folder upload, nothing else is skipped: remove
node_modulesand build output before archiving to keep the upload small. - Symbolic links are allowed only when they point inside the archive. "Files that would land outside the archive, and links that leave it, are rejected."
Archive limits
| Limit | Value |
|---|---|
| Formats | .zip, .tar, .tar.gz, .tar.bz2, .tar.xz, .tar.zst (not 7z or rar) |
| Archive file size | 300 MB |
| Unpacked size | 300 MB, whatever the compression |
| Files and folders in the archive | 100,000 |
| Zip compression | Stored or Deflate (the standard). Other methods are refused: re-create the zip with standard compression. |
| Encrypted zips | Not supported. |
Errors you may see: "Choose a .zip, .tar, .tar.gz, .tgz, .tar.bz2, .tar.xz or .tar.zst file.", "7z and rar are not supported; repack as .zip or .tar.gz.", "This archive is larger than 300 MB.", "Source archive contains too many entries", "Source archive exceeds its size limit", "Encrypted zip archives are not supported", and "Source archive is empty".
CLI
The CLI does the whole thing in one command. Run synq deploy --folder inside the folder to upload it. It
packages the folder, uploads it, detects the stack, creates the project (or reuses the linked one), and
deploys it, the same pipeline as the browser upload.
# From inside your project folder:
synq deploy --folder --name my-app --watch--nameis only a fallback name. The detected name wins: thenamefield inpackage.jsonwhen the folder has one, otherwise a name Synq generates for the upload. To choose the project, usesynq initor--project <id>(below).--watchfollows the build logs in your terminal until it finishes. Leave it off and Synq prints a command to follow the logs later.--server <id>picks the server (seesynq server list).
Deploying inside a Git repository?
--folder uploads the files directly, even from a Git checkout. Without it, synq deploy in a Git
repository uses the Git flow. Outside Git, --name also opts into a folder upload.
Run it from your app's source directory: uploading the temporary directory, or any folder that contains
it, is refused so that staging archives never end up inside your source. If TMPDIR points inside your
app, set it somewhere else.
Deploy to the same project again
Point the CLI at the project explicitly, or a repeat deploy can create a new project. A folder whose
package.json has a name reuses the project with that name, but a folder without one gets a new
generated name on every run.
Link the folder once with synq init, or pass --project <id> on each run:
synq init # pick a project to link this folder to
synq deploy --folder # uploads this folder to the linked project
synq deploy --folder --project <project-id> # or target a project without linkingsynq init writes a small .synq/project.json file so later commands know which project this folder
belongs to. It links to a project that already exists, so create one first (with a folder deploy, or
in the panel).
After the first deploy
- Redeploy rebuilds the files you uploaded last time. To ship changed files, upload again (the CLI
in a folder linked with
synq initis the quickest), or connect a repository under Source & Triggers → Source (Link a Repository) so pushes can deploy. - There is no push webhook for uploaded code. To trigger redeploys from outside, use a deploy hook.
Troubleshooting
“That folder looks empty” when you pick it
Everything in the folder was on the skip list (like node_modules and .git), or you picked a folder with
no source in it. Choose the folder that contains your app's code.
The build failed
Open the build screen and read the last few red lines; that is the real reason. First-time failures are almost always a missing build command, a missing environment variable, or the app listening on the wrong port. See Troubleshooting → Deployments.
Related guides
Deploy from any Git URL
Deploy a repository from GitLab, Bitbucket, Gitea, Forgejo, Codeberg or your own Git server, over HTTPS or SSH, with an access token or a deploy key Synq generates. Covers SSH host key pinning, branches, monorepos and changing the source later.
Deploy a Docker image
Run a prebuilt container image from Docker Hub, GitHub Container Registry or any private registry. Nothing is cloned or built. Covers registry credentials, ports, environment variables and tracking new versions.