Skip to main content
Menu
On this page

Formbricks alternative when you would rather not run the stack

Compare Formbricks with Fillo when self-hosting is not the goal: your own components render the fields, uploads go to storage you connect, and there are no services to operate.

Product forms without the stack

Formbricks gives you the whole survey platform to run. Fillo is for when you'd rather compose the form from your own components and operate nothing — Fillo keeps the schema, responses, and files behind them.

Compose the fields in your own tree.

Fillo controls are components you restyle or replace — not a rendered survey you re-skin with CSS.

app.acme.co/setup/feedback

Setup feedback

Powered by Fillo

Storage is connected, not configured.

Connect Drive, Box, or an S3-compatible bucket once — uploads go browser-direct with no IAM, bucket policy, or CORS rules to write.

Conditions are data, not code.

The same visibility rule renders the field in your app and gates what Fillo's server accepts.

Responses without running a database.

Answers, files, versions, and delivery state live in a workspace you don't have to operate.

Formbricks is an open-source survey platform. Use its cloud, or run the whole thing yourself with Docker: responses stay on infrastructure you control, and the source is there to read and patch. Surveys go out as links, or as in-app surveys delivered by its JavaScript SDK.

Fillo is hosted and does not offer self-hosting. It fits a different moment: the form belongs on a route inside your product, rendered by your own components, and nobody wants to own a survey stack.

Which should you choose?

When Fillo fits

  • Nobody wants to run Postgres, object storage, and certificate renewal for a form.
  • The form is part of a product flow: your route, your components, your submit button.
  • Files should go browser-direct to Google Drive, Box, or S3-compatible storage you connect once in settings.
  • One typed schema should drive the fields, client checks, server checks, visibility, and the response record.

When to stay on Formbricks

  • The requirement is "it runs on our infrastructure." Fillo has no self-hosted edition. If data residency put Formbricks on the list, Formbricks is the honest answer and the comparison ends here. Staying keeps self-hosting a standing job: database, object store, certificates, upgrades, backups.
  • You want the source. Reading, forking, and patching it is a real advantage Fillo cannot match. The cost is that what you would otherwise buy — storage wiring, availability, recovery — is yours to design.
  • You run in-app surveys with targeting: this segment, after this event, with recontact and cooldown rules. That is Formbricks' core job and Fillo does not do it. The cost shows on the other side: for a form that has to look like it belongs in the page, the SDK gives you a survey to restyle, not fields to compose.

What changes in your app

Formbricks publishes @formbricks/js on npm. Initialize it once with your workspace ID and app URL; from there it decides which survey to show and renders it, and you customize with CSS over what it draws.

ts
import formbricks from "@formbricks/js";

formbricks.setup({
  workspaceId: "<workspace-id>",
  appUrl: "https://app.formbricks.com",
});

With @usefillo/react, the fields are components in your own tree:

tsx
import { Fillo, when, createClient } from "@usefillo/react";

const client = createClient({ key: process.env.NEXT_PUBLIC_FILLO_KEY });

export function SetupFeedback() {
  return (
    <Fillo.Form id="setup-feedback" title="How did setup go?" client={client}>
      <Fillo.Rating id="ease" label="How easy was setup?" max={5} required />
      <Fillo.LongText
        id="blocked"
        label="What got in the way?"
        visibleIf={when("ease").lt(4)}
      />
    </Fillo.Form>
  );
}

Keep the default styles, pass your own class names, or swap a field for your own component. That visibleIf condition is data — a field ID, an operator, a value — so the same rule decides what renders and what Fillo's server accepts.

Key differences

DecisionFilloFormbricks
Operating modelHosted; nothing to runOpen source; Formbricks Cloud, or self-host the database, object storage, and reverse proxy
Rendering in your appYour React or DOM components, a fillo-form custom element, or a hosted pageSDK that displays Formbricks-rendered surveys, restyled with scoped CSS; link surveys by URL or iframe
File uploadsConnect a provider in settings; the browser uploads directly and Fillo verifies completionS3-compatible storage you configure: environment variables, IAM policy, bucket policy, CORS
Working with responsesGrid, versions, CSV, Management API, signed webhooksYour own instance, or Formbricks Cloud
Data residencyFillo-hostedSelf-host to keep processing on your infrastructure

Uploads are where the models diverge most concretely. Formbricks' file uploads documentation states that S3-compatible storage is required, and that the File Upload and Picture Selection question types stay disabled until it is configured: the S3_* variables, an IAM policy, a bucket policy, and a CORS rule without which browser uploads fail. The provider must also implement the S3 POST Object operation, and the same page names Backblaze B2 as incompatible for that reason. Checked against the self-hosting guide on August 6, 2026.

Before you switch

Fillo will not satisfy a self-hosting requirement, and it has no in-app targeting engine. It also starts a new response history: existing Formbricks responses stay where they are and cannot be imported with schema versions and delivery state. Fillo's transit storage is a starting lane, not a destination — 10 MB per file, 100 MB of active files per workspace, and completed files expire after seven days. Durable file workflows connect your own storage.

What you would need to change

Existing Formbricks setupExpected work
A link survey shared by URLRebuild the fields as a Fillo form, then publish the hosted page or render it on your own route
An in-app survey with display rulesDecide where the form belongs in your UI and render it there
A self-managed S3 bucketConnect the same storage in settings and retire the CORS, IAM, and endpoint plumbing
Webhooks into your backendReconnect each one, verify the signature, deduplicate on the delivery ID

Next step

Open the editor and rebuild one real form on a route in your app before deciding about the rest.

Updated

Was this page helpful?