When I first started working with Flutter, I always installed packages from pub.dev using the usual command:

flutter pub add package_name

This command would download the package, install it locally, and make it available to my project. But as I progressed in my Flutter development journey, I encountered situations where I didn’t want to install the package locally—or at least not in the traditional way. That’s when I learned how to reference packages through a Git or hosted link, and it made a huge difference in how I manage dependencies.

In this blog, I’ll walk you through how I use packages without downloading them in the typical way, and why I think it’s a powerful and flexible approach.

Why I Use Packages Through a Link

There were a few key reasons why I started using packages directly via links:

  • Sometimes I was testing unpublished or work-in-progress packages.
  • I needed to use private packages that weren’t on pub.dev.
  • Occasionally, I’d fork a package to fix a bug or add a feature.
  • I worked with monorepos, where multiple packages were stored in one Git repository.
  • In enterprise environments, I dealt with internal pub servers.

Instead of downloading and managing these packages manually, I simply referenced them via a link—usually a Git URL—and let Flutter handle the rest.

How I Use Git to Reference a Package

One of the easiest ways I’ve found to call a package via link is by pointing to its Git repository in pubspec.yaml.

Example: Using a GitHub Repo

Here’s how I referenced the http package from a forked GitHub repository:

dependencies:
  http:
    git:
      url: https://github.com/username/http.git
      ref: main

This approach cloned the repository into my local cache and made the package available to my project—no flutter pub add or pub.dev download needed.

Locking to a Specific Commit

To avoid surprises when the remote repo changes, I usually point to a specific commit like this:

dependencies:
  http:
    git:
      url: https://github.com/username/http.git
      ref: 28e8a9c2d145a5a31de903a1fcd00d7f72aa73f6

That way, I know exactly which version I’m using.

How I Reference a Subdirectory Package in a Monorepo

I sometimes work with monorepos that contain multiple packages. Here’s how I reference just one subpackage from a shared repo:

dependencies:
  my_utils:
    git:
      url: https://github.com/username/shared-packages.git
      path: packages/my_utils
      ref: stable

This method has been super helpful for me when building internal tools or shared utilities across teams.

How I Use Custom Package Servers

In a corporate setting, I once had to pull packages from a private pub server instead of pub.dev. Here’s how I did that:

dependencies:
  internal_package:
    hosted:
      name: internal_package
      url: https://packages.mycompany.com
    version: ^1.2.0

It required the backend team to set up a custom Dart package server, but once that was ready, I could treat those packages just like any other dependency.

How I Used a .tar.gz Archive as a Package Source

Although I rarely use this method, there was a time when I needed to work in an offline environment. I hosted a .tar.gz archive of a Dart package on a local server and used it like this:

dependencies:
  mycustompackage:
    hosted:
      name: mycustompackage
      url: https://myserver.com
dependencies:
  mycustompackage:
    hosted:
      name: mycustompackage
      url: https://myserver.com
    version: 1.0.0

This setup isn’t common, but it came in handy when I was working in an isolated environment without internet access.

My Code Example: Using a Git-Linked Package in Flutter

To show you a real use case, I created a simple demo using a package called math_utils from GitHub.

pubspec.yaml

dependencies:
  flutter:
    sdk: flutter

  math_utils:
    git:
      url: https://github.com/example/math_utils.git
      ref: main

main.dart

import ’package:flutter/material.dart’;
import ’package:mathutils/mathutils.dart’; // Imported from Git

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final result = MathUtils.add(10, 5); // Example method from the package

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Git Package Example")),
        body: Center(
          child: Text("10 + 5 = $result"),
        ),
      ),
    );
  }
}

After running flutter pub get, the package was pulled directly from the GitHub repo and worked just like a package from pub.dev.

What I Learned About How Flutter Handles Linked Packages

Once I understood how this worked under the hood, it all made more sense. Here’s what happens when I reference a package this way:

  1. Flutter clones or fetches the package from the given URL.
  2. It stores the package in .pub-cache.
  3. The version is locked in pubspec.lock.
  4. My project uses it just like a locally downloaded package.

This all happens automatically when I run flutter pub get.

Pitfalls I Ran Into (And How I Handled Them)

Problem

  1. Remote repo changed unexpectedly
  2. CI builds were slow
  3. Lost internet = broken build
  4. Forgot which repo version I used

What I Did

  • Used commit hashes instead of branch names
  • Cached .pub-cache in the CI environment
  • Switched to a local path: dependency for dev
  • Added comments with commit URLs in pubspec.yaml

Why This Matters to Me

Learning how to call Flutter packages through a link instead of downloading them conventionally changed the way I work. It gave me more flexibility, especially when I was:

  • Testing changes in a fork before publishing.
  • Sharing utilities across multiple apps via Git.
  • Working with internal, unreleased packages.
  • Collaborating with teammates on packages under development.

It’s an essential skill for advanced Flutter development, and it’s saved me countless hours in both small and large projects.

Our Trusted
Partner.

Unlock Valuable Cloud and Technology Credits

Imagine reducing your operational costs by up to $100,000 annually without compromising on the technology you rely on. Through our partnerships with leading cloud and technology providers like AWS (Amazon Web Services), Google Cloud Platform (GCP), Microsoft Azure, and Nvidia Inception, we can help you secure up to $25,000 in credits over two years (subject to approval).

These credits can cover essential server fees and offer additional perks, such as:

  • Google Workspace accounts
  • Microsoft accounts
  • Stripe processing fee waivers up to $25,000
  • And many other valuable benefits

Why Choose Our Partnership?

By leveraging these credits, you can significantly optimize your operational expenses. Whether you're a startup or a growing business, the savings from these partnerships ranging from $5,000 to $100,000 annually can make a huge difference in scaling your business efficiently.

The approval process requires company registration and meeting specific requirements, but we provide full support to guide you through every step. Start saving on your cloud infrastructure today and unlock the full potential of your business.

exclusive-partnersexclusive-partners

Let's TALK

Let's TALK and bring your ideas to life! Our experienced team is dedicated to helping your business grow and thrive. Reach out today for personalized support or request your free quote to kickstart your journey to success.

DIGITAL PRODUCTUI/UX DESIGNDIGITAL STUDIOBRANDING DESIGNUI/UX DESIGNEMAIL MARKETINGBRANDING DESIGNUI/UX DESIGNEMAIL MARKETING
DIGITAL PRODUCTUI/UX DESIGNDIGITAL STUDIOBRANDING DESIGNUI/UX DESIGNEMAIL MARKETINGBRANDING DESIGNUI/UX DESIGNEMAIL MARKETING