# Git

- Tool: FlutterFlow
- Difficulty: Beginner
- Time required: 20 minutes
- Last updated: July 2026

## TL;DR

Connect FlutterFlow to Git using the built-in GitHub integration under Settings → Integrations → GitHub. FlutterFlow commits your generated Flutter project to a GitHub repo and supports branching so teams can review changes via pull requests before merging. This requires the Pro plan ($70/mo). FlutterFlow is always the source of truth — hand-edits to generated files get overwritten on the next export.

## Version-Controlling Your FlutterFlow App with Git

Every FlutterFlow app compiles to a standard Flutter project — a `pubspec.yaml`, a `lib/` folder full of generated Dart files, plus `android/`, `ios/`, and `web/` targets. That output is code, and code benefits from version control. Git lets you snapshot every export, roll back a broken screen, and collaborate without stepping on each other's work. FlutterFlow's native GitHub integration handles the push so you never need to touch a terminal.

The integration lives in Settings → Integrations → GitHub. Once you authorize FlutterFlow to access your GitHub account (personal or organization), you pick or create a repository, and FlutterFlow is ready to push. Each time you click the push button in FlutterFlow, it commits the full generated project — the diff shows exactly what changed between exports. Git is free; GitHub has a generous free tier; the only cost gate is FlutterFlow's Pro plan ($70/mo), which is required for code export.

The most important mental model: FlutterFlow is your source of truth, not the repository. The repo is a downstream artifact. If you hand-edit a generated file in GitHub or a local editor and then push from FlutterFlow again, your edits are silently overwritten. The safe workflow is to keep all visual work inside FlutterFlow, use branches to review diffs before merging, and only hand-edit files you plan to 'freeze' in a fork — understanding you won't re-import that screen into FlutterFlow.

## Before you start

- A FlutterFlow account on the Pro plan ($70/mo) — the Free and Standard ($30/mo) plans do not include code export or GitHub push
- A GitHub account (free tier is sufficient); organization access if you want to push to an org repo
- A FlutterFlow project that is ready to version (ideally beyond the initial scaffold stage)
- Basic understanding of what a branch and a pull request are (a pull request is a request to merge one branch into another — it's how your team reviews changes before they go live)

## Step-by-step guide

### 1. Upgrade to Pro and open the GitHub integration panel

Version control via GitHub requires FlutterFlow's Pro plan. If you're on Free or Standard, open your account settings and upgrade to Pro ($70/mo). Once on Pro, open your FlutterFlow project and navigate to the left-hand toolbar. Near the bottom, click the gear icon to open Settings, then choose Integrations from the settings menu. You will see a GitHub section. This is the only place you configure the Git connection — there is no terminal, no `git remote add`, no SSH key setup. Everything is handled through FlutterFlow's OAuth flow with GitHub. If your project is a team project, make sure the person setting this up has admin access to the target GitHub organization or repository, because the OAuth authorization needs permission to create and push to repos.

**Expected result:** You can see the GitHub integration card inside Settings → Integrations, and the 'Connect GitHub' button is enabled.

### 2. Authorize GitHub and pick or create a repository

Click 'Connect GitHub' inside the integration panel. A GitHub OAuth popup opens in your browser — log in if you aren't already, then click 'Authorize FlutterFlow'. If your FlutterFlow project belongs to an organization, you'll also need to click 'Grant' next to that organization in the OAuth screen, otherwise the repo picker won't show org repos. After authorizing, return to FlutterFlow and use the repository dropdown to either pick an existing empty repo or create a new one. For a brand-new project, create a new repo with a meaningful name — something like `my-app-flutter` or `client-name-app`. Make sure the repo is initialized as empty (no README) so FlutterFlow's first push doesn't conflict with existing content. If you're connecting to an existing repo that already has commits, the first FlutterFlow push will overwrite the working tree — branch first before connecting if the repo has important hand-written code.

**Expected result:** The GitHub integration panel shows your connected repository name and a green connected status indicator.

### 3. Push your first commit of the generated Flutter project

With the repo connected, you're ready to push your first commit. In the top-right area of the FlutterFlow editor you'll see a GitHub icon (sometimes labelled 'Push to GitHub' or showing the GitHub octocat logo). Click it. A dialog appears asking for a commit message — write something descriptive like 'Initial project scaffold with home screen and auth flow'. Then click 'Push'. FlutterFlow will package the entire generated Flutter project — `pubspec.yaml`, `lib/main.dart`, all screen Dart files, assets, platform folders — and commit it to the `main` branch of your connected repo. The push takes 10–30 seconds depending on project size. When it completes, open GitHub in a new tab and confirm you can see the commit in the repository. You should see a standard Flutter project structure: `lib/`, `android/`, `ios/`, `web/`, `pubspec.yaml`, `README.md`. This is now the same code a developer would open in VS Code or IntelliJ IDEA to run locally.

**Expected result:** GitHub shows your first commit with the full Flutter project structure visible in the repository file browser.

### 4. Create a feature branch for new work and export to it

The best Git workflow for FlutterFlow is branch-per-feature: make changes in FlutterFlow, push to a dedicated branch, review the diff via a pull request (PR), and merge to `main` only when the feature is ready. To create a branch, open the branch selector in FlutterFlow's GitHub integration panel — it's usually a dropdown labeled with the current branch name (e.g. 'main'). Type a new branch name like `feature/profile-screen` and press Enter to create it. From now on, every push will go to that branch. Make your changes in FlutterFlow — add screens, adjust widgets, configure data types — then push with a descriptive commit message. On GitHub, you'll see the new branch appear with your commits. Open a pull request from `feature/profile-screen` → `main` to review the Dart diff before it lands in production. The diff shows every generated file that changed — which screens were added, which widget properties shifted, which navigation routes were updated.

**Expected result:** GitHub shows your feature branch with commits separate from main, and you can open a pull request comparing the two branches.

### 5. Review the diff and merge to main

Open the pull request on GitHub. You'll see a 'Files changed' tab that lists every Dart file FlutterFlow modified. Scan through it: did the new booking screen appear in `lib/pages/booking/booking_widget.dart`? Did the navigation route register correctly in `lib/app_state.dart`? This review step is where you catch accidental changes — sometimes editing one FlutterFlow screen touches shared components and the diff reveals unintended side effects. Once you're satisfied, click 'Merge pull request' on GitHub. The changes land on `main`. In FlutterFlow, switch the branch selector back to `main` to confirm the integration is pointing at the right branch for the next feature. You don't need to pull anything into FlutterFlow — the editor doesn't read from GitHub. GitHub is a downstream snapshot; FlutterFlow's database is always the live version of the app.

**Expected result:** The pull request is merged and main on GitHub reflects the new feature screens from your latest FlutterFlow export.

### 6. Establish source-of-truth rules for your team

The most common source of pain with FlutterFlow + Git is misunderstanding which side owns the code. The rule is simple: FlutterFlow is the source of truth for all generated files. The GitHub repo is a read-mostly archive and CI trigger — never a place to hand-write Dart that you expect to survive. If a developer opens the repo, edits a widget Dart file locally, and commits that change to the branch, the next FlutterFlow push will silently overwrite their edit. Custom code that must survive exports belongs in FlutterFlow's own Custom Code panel (Custom Actions, Custom Functions, Custom Widgets) — FlutterFlow preserves those files even when regenerating other screens. Secrets — Firebase config, API keys, environment tokens — must never be committed to the repo; add `google-services.json`, `GoogleService-Info.plist`, and any key files to `.gitignore` immediately after the first push. For CI/CD pipelines that pick up the exported code (for example, a GitHub Actions workflow that runs `flutter test` and builds an APK), store secrets in GitHub Actions Secrets and inject them at build time, not in the Dart source.

```
# .gitignore additions after FlutterFlow export
google-services.json
GoogleService-Info.plist
*.keystore
*.jks
key.properties
.env
lib/firebase_options.dart   # if it contains real project IDs — regenerate in CI
```

**Expected result:** Your team has agreed on a workflow: all screen work happens in FlutterFlow, custom code lives in FlutterFlow's Custom Code panel, and the GitHub repo is never hand-edited in generated files.

## Best practices

- Treat FlutterFlow as the source of truth — never hand-edit generated files in the repo expecting the changes to survive the next export.
- Use feature branches (e.g. feature/booking-screen) so every export is reviewable as a pull request before landing on main.
- Write descriptive commit messages for every FlutterFlow push — 'add profile edit screen and image upload action' is far more useful than 'update' when debugging a regression.
- Add google-services.json, GoogleService-Info.plist, and keystores to .gitignore immediately after the first push — secrets in a repo are compromised secrets.
- Put custom Dart logic in FlutterFlow's Custom Code panel (Custom Actions / Functions) — these files are preserved between exports unlike generated screens.
- Coordinate exports in small teams: agree that only one person pushes at a time, or use per-person branches, to avoid merge conflicts in generated files.
- Review the GitHub diff on each pull request before merging — the Files Changed tab reveals if a FlutterFlow export accidentally touched shared components you weren't expecting to change.
- Store CI/CD secrets (API keys, signing certs) in GitHub Actions Secrets and inject them at build time — never bake them into the committed Flutter project.

## Use cases

### Team of two founders building a marketplace app

Two co-founders split FlutterFlow work: one builds the buyer flow, the other builds the seller dashboard. Each works on a named feature branch so their exports don't collide. They open a pull request to review each other's diff before merging to main.

Prompt example:

```
Set up a feature branch in FlutterFlow for the buyer onboarding screens, push the export, then open a GitHub pull request for review before we merge to main.
```

### Solo founder releasing weekly app updates

A solo founder treats each weekly FlutterFlow export as a versioned release. The GitHub commit history becomes a changelog they can share with beta testers, making it easy to roll back if a new screen breaks the navigation flow.

Prompt example:

```
Push this week's FlutterFlow changes to GitHub with a commit message that describes the new profile screen and push-notification support we added.
```

### Client project with an agency review gate

A freelance developer exports from FlutterFlow into a feature branch, opens a pull request for the client's tech lead to review the generated Dart diffs, and only merges after approval — keeping an audit trail of every change delivered.

Prompt example:

```
Connect the FlutterFlow client project to GitHub, create a branch called feature/booking-flow, push the latest export, and send the pull request link to the client for review.
```

## Troubleshooting

### GitHub push fails with 'Repository not found' or 'Authentication failed'

Cause: The GitHub OAuth token FlutterFlow stored has expired or the repo was transferred/renamed after the connection was established.

Solution: Go to Settings → Integrations → GitHub, disconnect the integration, and re-authorize GitHub OAuth. If the repo was renamed, update the repo selector to point at the new name. Also check that FlutterFlow still has the correct organization permission granted in your GitHub OAuth Apps settings (github.com → Settings → Applications → Authorized OAuth Apps).

### Hand-edited Dart files in the repo disappeared after the next FlutterFlow push

Cause: FlutterFlow regenerates all files in lib/ (except Custom Code files) on every export. Any file edited outside of FlutterFlow's Custom Code panel gets overwritten.

Solution: Move any logic you want to survive exports into FlutterFlow's Custom Code panel (left nav → Custom Code → + Add → Action or Function). Custom action and function files are preserved between exports. If you absolutely need to hand-edit a generated file as a one-time fix, freeze the branch (don't push from FlutterFlow again) or accept the loss on the next export.

### Merge conflict when two team members push overlapping FlutterFlow exports

Cause: Both teammates exported from FlutterFlow while working on overlapping screens, creating divergent commits on the same branch that GitHub can't auto-merge.

Solution: Coordinate by using separate feature branches — each person exports to their own branch and opens a pull request. Merge one PR first, then have the second person re-export from FlutterFlow to pick up the merged state (FlutterFlow doesn't read from GitHub, so this is just a reminder to coordinate on who pushes last). For GitHub conflict resolution, the 'FlutterFlow export' side of the conflict is almost always the correct one to keep.

### The 'Push to GitHub' button is greyed out or missing

Cause: The FlutterFlow project is on the Free or Standard plan, which does not include GitHub push / code export.

Solution: Go to Account Settings → Plan and upgrade to Pro ($70/mo). The GitHub push button appears immediately after the plan upgrade is confirmed. If you see the button but it's greyed out, check that you have completed the GitHub authorization step — an incomplete OAuth flow leaves the button inactive.

## Frequently asked questions

### Does FlutterFlow support GitLab or Bitbucket directly?

No. FlutterFlow's built-in Git integration only supports GitHub. To use GitLab or Bitbucket, you push to GitHub first and then set up a repository mirror on the other platform. The mirror is one-directional — changes made directly in GitLab or Bitbucket do not flow back to FlutterFlow.

### What happens to my custom Dart code when I push from FlutterFlow?

Custom Actions, Custom Functions, and Custom Widgets you create inside FlutterFlow's Custom Code panel are preserved across exports — FlutterFlow does not regenerate those files. However, any Dart code you add manually to a generated file (like a screen widget) outside of FlutterFlow will be overwritten on the next push. The safe pattern is always to add custom logic through FlutterFlow's Custom Code panel.

### Can I pull changes from GitHub back into FlutterFlow?

No. FlutterFlow is a one-way export tool — it writes to GitHub, but it does not read from GitHub. Your FlutterFlow project database (stored in FlutterFlow's cloud) is always the authoritative source. There is no 'import from GitHub' button. This means you cannot have a developer push hand-written Dart to the repo and see those changes in the FlutterFlow editor.

### Do I need a paid GitHub plan to use this integration?

No. GitHub's free tier supports unlimited public and private repositories, and FlutterFlow's GitHub push works with free GitHub accounts. The paid requirement is on the FlutterFlow side — you need the Pro plan ($70/mo) to enable code export and GitHub push.

### How do I set up CI/CD to test and build my FlutterFlow app automatically?

After the FlutterFlow → GitHub push, the repo is a standard Flutter project. You can add a .github/workflows/flutter.yml GitHub Actions file that runs flutter pub get, flutter test, and flutter build apk --release (or flutter build web). Store signing certificates and API keys in GitHub Actions Secrets, never in the committed Dart code. The FlutterFlow push triggers the workflow automatically on each commit.

---

Source: https://www.rapidevelopers.com/flutterflow-integrations/git
© RapidDev — https://www.rapidevelopers.com/flutterflow-integrations/git
