> For the complete documentation index, see [llms.txt](https://wong-coupon.gitbook.io/flutter/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wong-coupon.gitbook.io/flutter/architecture-code/package.md).

# Package

**Creating and managing packages significantly reduces coding time, allows for code reuse, and makes project maintenance easier. Below are some key benefits of using packages:**

* **Code Reusability**

  When you create packages for common features or components, you can reuse them across multiple projects without rewriting code. This saves both time and effort.
* **Easy Management and Maintenance**

  Packages are well-organized, making them easy to update and maintain. When a feature needs to be changed or upgraded, you can simply update the package without affecting the entire project.
* **Enhanced Consistency**

  Using packages ensures that your code remains consistent and follows the same rules and standards across different projects.
* **Faster Development**

  With pre-built packages, you can focus on developing project-specific features without spending time on fundamental components.
* **Collaboration and Sharing**

  Packages can be shared with the community or within a development team, enhancing collaboration and leveraging collective knowledge.
* **Reduced Errors**

  Reusing well-tested and stable packages minimizes the risk of encountering new bugs during application development.

Below is a detailed guide on how to create and manage packages:

## How I Set Up Packages for Use Across Multiple Projects

<figure><img src="/files/RL80EgR26nKvxXpXikv7" alt=""><figcaption><p>How I Set Up Packages for Use Across Multiple Projects</p></figcaption></figure>

I have created a directory named **packages** to store all the packages I develop.

I categorize them into two types:

* The first type belongs to **ancestor\_core**, which consists of foundational packages where I have encapsulated functions following an object-oriented programming style. When using these packages, you simply call them without worrying about the complex internal processing and setup.
* The second type consists of **UI packages**, which contain all the UI-related widgets and components. These help minimize a significant amount of code and can be reused in future projects.

Now, let's dive into one of them: **fire\_core**.

<figure><img src="/files/NUBdVliO2HPjmu0SMVOO" alt=""><figcaption><p><strong>fire_core</strong>.</p></figcaption></figure>

This package stores all the Firebase-related code I have written. In the future, if a new project requires Firebase, I can simply import this package and reuse the previously written code.

## Setting Up a Package

#### Step 1: Run

```bash
cd pathTo/packages

flutter create --template=package hello_core
```

#### Step 2: Configure Lint in `pubspec.yaml`

```bash
cd pathTo/hello_core
flutter pub add lint
flutter pub add test
flutter pub add mockito
```

The **lint** package helps detect errors in Dart code, ensuring a clean and well-formatted codebase.\
[Learn more](https://pub.dev/packages/lint)

#### Step 3: Replace `analysis_options.yaml`

Replace the **project's** `analysis_options.yaml` file to include error analysis configurations from the `lint` package.

```yaml
# This file configures Dart analysis using rules from package:lint

include: package:lint/strict.yaml # For production applications
# include: package:lint/casual.yaml # For samples, hackathons, and non-production code
# include: package:lint/package.yaml # For packages with public APIs

# Exclude generated files from Dart analysis
analyzer:
  errors:
    invalid_annotation_target: ignore
  plugins:
    - custom_lint
  exclude:
    - packages/mason_core/**
    - '**.freezed.dart'
    - '**.g.dart'

# Customize linting rules as desired. A complete list of rules can be found at:
# https://dart-lang.github.io/linter/lints/options/options.html
linter:
  rules:
    - unawaited_futures
rules:
  # Utility classes are great!
  # avoid_classes_with_only_static_members: false

  # Keep constructors at the top of each class
  # sort_constructors_first: true

  # Good practices, but optional
  prefer_double_quotes: true
  prefer_single_quotes: true
  avoid_dynamic_calls: true
  lines_longer_than_80_chars: true
  avoid_classes_with_only_static_members: true
  use_named_constants: true
```

For **package-level** `analysis_options.yaml`, replace it with:

```yaml
include: ../../analysis_options.yaml
```

[Learn more](https://docs.flutter.dev/packages-and-plugins/developing-packages)

To quickly generate the folder and file structure as shown in the images, you can use **Mason**. If you're not familiar with Mason, check out my **brick** here: [dr\_folder\_package](https://brickhub.dev/search?q=dr_folder_package)

## Synchronizing Package Folders Across Different Projects

My idea is to **sync all packages using Git**, with each package in a project stored in a separate branch. Later, you can merge them all into one if needed.

### Setting Up in a Project

The idea is to create a **packages project** on Git and link it to our local `packages` directory.

```bash
git clone https://gitlab.com/yourdomain/packages.git
cd pathTo/packages
git checkout master
git branch feature-snap
git checkout feature-snap
```

If the directory already exists:

```bash
cd pathTo/packages
git init
git remote add origin https://gitlab.com/yourdomain/packages.git
git fetch
```

You might find this process a bit tedious, so why not create a **separate package project** that is independent of the main project?

The benefit of my approach is that when coding, you can **easily add, edit, and search within packages** while keeping all package code within the main project. This ensures safety in case someone **locks your packages on Git**.

### Usage

**Step 1: Commit Changes**

```bash
cd pathTo/packages
git add .
git commit -am "changed"
git push origin feature-snap
```

**Step 2 (Optional): Push to Remote**

```bash
cd pathTo/packages
git fetch
git pull origin master --rebase
```

## How to Use Packages in a Real Project

Let's say I have a function to **print JSON to the log in a properly formatted way**. I will put it inside a class named `string.dart`, which is located in a package called **dart\_core**, as shown below:

<figure><img src="/files/zM8nkl6SbHURv9NXowYF" alt=""><figcaption><p>How to Use Packages in a Real Project</p></figcaption></figure>

#### Step 1: Define the Function in `string.dart`

```dart
import 'dart:convert';

extension MyStringHelper on String {
  String get myPrintStringJson {
    if (isJSON(this)) {
      const JsonDecoder decoder = JsonDecoder();
      const JsonEncoder encoder = JsonEncoder.withIndent('  ');

      final object = decoder.convert(this);
      final prettyString = encoder.convert(object);
      var string = "";
      prettyString.split('\n').forEach((element) => string = '$string\n$element');
      return string;
    } else {
      var format = this;
      format = format.replaceAll('{', '\n{\n  ');
      format = format.replaceAll(',"', ',\n  "');
      format = format.replaceAll('}', '\n}');
      format = format.replaceAll('":', '" : ');
      format = format.replaceAll('[', '[\n  ');
      format = format.replaceAll(']', '\n]');
      return format;
    }
  }
}
```

#### Step 2: Export It in `dart_core.dart`

```dart
export 'dart/src/string.dart';
```

#### Step 3: Declare the Package in `pubspec.yaml`

```yaml
dependencies:
  flutter:
    sdk: flutter
  
  dart_core:
    path: packages/ancestor_cores/dart_core
```

#### Step 4: Use It in Your Project

```dart
import 'package:dart_core/dart_core.dart';

myLog.warning((await myLocation.locationAccuracy).toString().myPrintStringJson);
```

And that completes the process of **creating and using a function inside a package**.

Now, you can **store and reuse** your best utility functions whenever needed. This method is especially useful for **Firebase projects**, as you can reuse the setup across multiple projects **without having to configure it again**.

[Buy Me a Coffee](https://buymeacoffee.com/ducmng12g) | [Support Me on Ko-fi](https://ko-fi.com/I2I81AEJG8)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://wong-coupon.gitbook.io/flutter/architecture-code/package.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
