> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bitfield.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Let many packages work together

> Combine Bitfield state, data names, and action requests so many packages cooperate without sharing private objects.

<div className="bf-article">
  <p className="bf-lead">
    When many packages need to cooperate, do not create one giant store that everyone imports. Let packages meet through Bitfield state, data names, and action requests.
  </p>

  A command center has a file tree, file editor, AI chat, project preview, notifications, keyboard shortcuts, and a sidebar. Each package has its own job. The user still needs one coherent product.

  The goal is cooperation without fusion: packages share public Bitfield handles instead of turning into one tangled codebase.

  ## Traditional app shape

  ```ts theme={null}
  import { appStore } from '../app-store';
  import { previewService } from '../project-preview/service';
  import { notificationService } from '../notifications/service';
  import { chatContext } from '../chat/context';

  export async function runEverything() {
    const file = appStore.fileTree.selectedFile;
    chatContext.attachFile(file);
    await previewService.refresh(appStore.currentProject);
    notificationService.setMode(appStore.settings.notificationMode);
  }
  ```

  This code is convenient because everything is reachable. It is dangerous for the same reason.

  ## Bitfield shape

  ```text theme={null}
  selected-file -> shared Bitfield state
  current-project -> shared Bitfield state
  project-preview-surface -> data name
  notification-mode.update -> action request
  chat.attach-context -> action request
  ```

  Each package uses the public name it needs. No package imports every other package.

  ## Cooperation map

  <div className="bf-lane-map" aria-label="Many packages cooperating through Bitfield">
    <div className="bf-lane-card">
      <span>State</span>
      <strong>selected-file</strong>
      <p>Editor, AI context, and breadcrumbs read the same product fact.</p>
    </div>

    <div className="bf-lane-card">
      <span>Input</span>
      <strong>project-preview-surface</strong>
      <p>Preview UI reads a prepared view of project status and URL.</p>
    </div>

    <div className="bf-lane-card">
      <span>Request</span>
      <strong>notification-mode.update</strong>
      <p>A settings surface asks the notification package to change mode.</p>
    </div>

    <div className="bf-lane-card">
      <span>Private</span>
      <strong>open menu</strong>
      <p>Temporary UI details stay inside the package rendering them.</p>
    </div>
  </div>

  ## Larger chain

  Start with a normal product flow:

  ```text theme={null}
  1. User selects a file.
  2. Editor opens that file.
  3. AI context panel uses that file.
  4. Preview panel shows the current project preview.
  5. Keyboard shortcut changes the selected agent.
  6. Notification package shows whether work finished.
  7. Help package provides context text for the command palette.
  ```

  Traditional app architecture tends to collapse that into one central store:

  ```ts theme={null}
  appStore.selectedFile = fileTreeStore.selectedFile;
  appStore.editor.open(appStore.selectedFile);
  appStore.ai.attachFile(appStore.selectedFile);
  appStore.preview.refresh(appStore.currentProject);
  appStore.selectedAgent = keyboardStore.nextAgent();
  appStore.notifications.mode = settingsStore.notificationMode;
  appStore.help.index = helpPackage.searchIndex;
  ```

  That looks convenient until every package depends on the central store shape and the central store imports every package.

  ### Shared names, separate packages

  ```text theme={null}
  selected-file -> product fact read by editor and AI context
  current-project -> product fact read by preview and package filters
  project-preview-surface -> data name rendered by preview shell
  selected-agent.update -> action request from keyboard or command palette
  notification-mode.update -> action request from settings or shortcuts
  getting-started-help -> data name from package-owned help content
  dropdown open state -> private UI state inside the surface
  ```

  Now each package meets the others through public facts, data names, and action names. There is no private central product object.

  ## What this prevents

  | Bad shape                                    | Why it breaks                                                       | Better shape                                                     |
  | -------------------------------------------- | ------------------------------------------------------------------- | ---------------------------------------------------------------- |
  | One giant app store.                         | Every feature depends on every other feature's private state shape. | Shared product facts in Bitfield.                                |
  | One central service imports all packages.    | Adding a package means editing the central service.                 | Packages expose inputs and targets.                              |
  | Shell coordinates package-specific UI rules. | Layout becomes business logic.                                      | Shell places; packages read/call.                                |
  | Code gets patched wherever it is easiest.    | The code compiles but boundaries collapse.                          | Choose state, input, target, private UI state, or package bytes. |

  React is one adapter that can show this chain. The chain itself is Runtime Kit: shared product facts, data names, action requests, private UI state, and package files.

  ## Complete translation example

  | Product need                     | Traditional answer              | Bitfield answer                           |
  | -------------------------------- | ------------------------------- | ----------------------------------------- |
  | Editor needs active file.        | Import file tree store.         | Read `selected-file`.                     |
  | AI chat needs active file.       | Import editor state.            | Read `selected-file`.                     |
  | Preview panel needs URL.         | Import project preview service. | Read `project-preview-surface`.           |
  | Button refreshes preview.        | Call preview implementation.    | Request `project-preview.refresh-status`. |
  | Keyboard changes selected agent. | Import selected-agent service.  | Request `selected-agent.update`.          |
  | Dropdown opens.                  | Global app store.               | Private UI state.                         |

  ## Add a new package without retangling

  Imagine you add a "recent activity" package.

  ### Traditional addition

  ```ts theme={null}
  import { editorStore } from '../editor/store';
  import { previewService } from '../project-preview/service';
  import { notificationSettings } from '../notifications/settings';

  export function RecentActivity() {
    return buildActivity(editorStore.file, previewService.status, notificationSettings.mode);
  }
  ```

  Bitfield addition:

  ```ts theme={null}
  const selectedFile = readInput('selected-file');
  const preview = readInput('project-preview-surface');
  const notificationMode = readInput('notification-mode');
  ```

  The new package reads the public facts it needs. Existing packages do not change.

  ### Central-store shortcut

  ```ts theme={null}
  recentActivityStore.copyFrom(appStore);
  ```

  ### Read public facts instead

  ```ts theme={null}
  const activityInputs = [
    readInput('selected-file'),
    readInput('project-preview-surface'),
    readInput('notification-mode'),
  ];
  ```

  ## Multi-package review checklist

  | Check                                                                 | Good answer                                      |
  | --------------------------------------------------------------------- | ------------------------------------------------ |
  | Does adding the new package require editing existing package imports? | No.                                              |
  | Does the shell branch on package-specific UI rules?                   | No. It places descriptors and surfaces.          |
  | Does one package become the central product store?                    | No. Shared facts live in Bitfield.               |
  | Can keyboard, command palette, and buttons request the same work?     | Yes. They send the same action request.          |
  | Can a non-React shell follow the same chain?                          | Yes. React is one adapter, not the architecture. |

  ## Why this scales past the first screen

  The first screen can survive traditional coupling. The tenth screen usually cannot. The problem is not that stores, services, or contexts are evil. The problem is that they make every feature depend on another feature's private state shape.

  Bitfield keeps the product language outside any one package:

  | Product language                       | Public name               |
  | -------------------------------------- | ------------------------- |
  | "The file the user is working on"      | `selected-file`           |
  | "The project the workspace is showing" | `current-project`         |
  | "The preview surface to render"        | `project-preview-surface` |
  | "Change the selected agent"            | `selected-agent.update`   |
  | "Search help"                          | `help.search`             |

  That is what lets package eleven join the product without becoming a patch inside package two.

  ## Review check

  When more than two packages are involved, do not solve it by creating `appStore`, `platformStore`, `globalState`, or `sharedService`. First classify each relationship:

  ```text theme={null}
  same fact needed by many packages -> Bitfield state
  prepared view from package material -> data name
  work to run -> action request
  visual-only detail -> private UI state
  bytes shipped with package -> package file
  ```

  ## Next

  * Start with the overview: [Build without tangled code](/runtime-kit/build-without-tangled-code)
  * Build a full example: [Placeable surface product loop](/runtime-kit/cookbook/placeable-surface-product-loop)
  * Review AI coding rules: [Rules for AI agents](/runtime-kit/build-without-tangled-code/rules-for-ai-agents)
</div>
