# Conductor: A View-Based Android Framework Without Fragments

> Conductor replaces Fragments with a lighter Controller and Router pair for single-Activity Android apps. It is a mature 3.x library with a 4.0 preview line, and the trade-off is that you take on the framework's lifecycle conventions instead of the platform's.

**bluelinelabs/Conductor** — A small, yet full-featured framework that allows building View-based Android applications

- Repository: https://github.com/bluelinelabs/Conductor
- Stars: 3,897 · Forks: 338
- Language: Java
- License: Apache-2.0
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/bluelinelabs-conductor

## What Conductor Solves for Single-Activity Android Apps

Android's Fragment API carries a reputation for lifecycle states that are hard to reason about, and Conductor's answer is to remove Fragments from the picture entirely. The README describes the Controller as "a lighter-weight and more predictable Fragment alternative with an easier to manage lifecycle." That is the whole pitch: you keep writing ordinary Android Views, but you stop routing them through FragmentManager.

The target reader is an Android developer building a single-Activity app. Conductor's README lists that as a first-class feature, alongside navigation and backstack handling, transitions between views, state persistence, and callbacks for onActivityResult and onRequestPermissionsResult. Those callbacks matter because once you have one Activity and no Fragments, you have lost the platform's built-in plumbing for delivering activity results to the screen that requested them. Conductor re-implements that plumbing at the Controller level.

The framework is explicitly architecture-agnostic. The README says it "does not try to force any design decisions on the developer" and notes that BlueLine Labs itself tends to use MVP or MVVM, while the library works equally well with MVC. That is a real design stance, not marketing: Conductor gives you a lifecycle and a navigation stack, and leaves state management to you.

## Controllers, Routers and Change Handlers: How the Pieces Fit

The README names four components. A Controller is the View wrapper that provides lifecycle management. A Router implements navigation and backstack handling, and is attached to an Activity or containing ViewGroup pair. A ControllerChangeHandler swaps the View of one Controller for the View of another. A RouterTransaction describes a push, including which change handler to use.

The split between Router and ControllerChangeHandler is the part worth understanding. The README states plainly that Routers "do not directly render or push Views to the container ViewGroup, but instead defer this responsibility to the ControllerChangeHandler specified in a given transaction." So the Router tracks the backstack and decides what should be on screen; the change handler decides how the swap looks. That means animation is a per-transaction decision rather than a global setting, and you can subclass ControllerChangeHandler when the built-in ones do not fit. Two convenience subclasses ship with the library: AnimatorChangeHandler, which uses an Animator, and TransitionChangeHandler, which uses the Lollipop Transition framework.

Nesting works through getChildRouter, called on a Controller to obtain a nested Router. The README gives Master/Detail as the motivating example. Memory behaviour is also a per-Controller choice: setRetainViewMode takes RELEASE_DETACH, which releases the view as soon as it is detached, or RETAIN_DETACH, which keeps the view alive while it is off screen for views that are expensive to recreate. That is a direct memory-versus-recreation trade-off exposed as an API rather than hidden behind a policy.

## Installing Conductor and Pushing a First Controller

Conductor is published to Maven Central under the com.bluelinelabs group. The README presents three installation options and names the current stable line as 3.2.0. The core artifact is com.bluelinelabs:conductor, with optional modules for AndroidX transition change handlers, a ViewPager PagerAdapter, and a ViewPager2 adapter. Add only the modules you use.

```gradle
def conductorVersion = '3.2.0'

implementation "com.bluelinelabs:conductor:$conductorVersion"

// AndroidX Transition change handlers:
implementation "com.bluelinelabs:conductor-androidx-transition:$conductorVersion"

// ViewPager PagerAdapter:
implementation "com.bluelinelabs:conductor-viewpager:$conductorVersion"

// ViewPager2 Adapter:
implementation "com.bluelinelabs:conductor-viewpager2:$conductorVersion"
```

For the 4.0 preview, the README says to use 4.0.0-preview-4 as the version number in any of those dependencies. For a snapshot build, use 4.0.0-SNAPSHOT and add the Sonatype snapshot repository, which the README shows as a maven block pointing at https://oss.sonatype.org/content/repositories/snapshots/ under allprojects.repositories.

On the code side, the README's minimal Activity attaches a Router to a container ViewGroup and sets a root Controller only when one is not already present. Note the two configuration calls: setPopRootControllerMode(PopRootControllerMode.NEVER) and setOnBackPressedDispatcherEnabled(true).

```kotlin
class MainActivity : AppCompatActivity() {

    private lateinit var router: Router

    override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)

      setContentView(R.layout.activity_main)

      val container = findViewById<ViewGroup>(R.id.controller_container)

      router = Conductor.attachRouter(this, binding.controllerContainer, savedInstanceState)
        .setPopRootControllerMode(PopRootControllerMode.NEVER)
        .setOnBackPressedDispatcherEnabled(true)

      if (!router.hasRootController()) {
        router.setRoot(RouterTransaction.with(HomeController()))
      }
    }
}
```

A Controller is then a class extending Controller that overrides onCreateView, inflates a layout, and returns the View. The README's example sets a TextView's text to "Hello World" to prove the view is live. After that, the demo module in the repository is the reference point: the README describes it as showing "all basic and most advanced functions of Conductor."

One practical note on the README itself: the Activity snippet calls Conductor.attachRouter with binding.controllerContainer while the line above it resolves findViewById<ViewGroup>(R.id.controller_container). Those two lines do not agree on how the container is obtained. Treat that snippet as illustrative and check the demo module for the version that compiles against your setup.

## Where Conductor Is the Wrong Choice

The most obvious limitation is that Conductor is not a drop-in replacement for Fragments. Any library in your dependency graph that expects a FragmentManager, a Fragment subclass, or a Fragment lifecycle will not cooperate with a Controller. If your app is already built around Fragments and works, migrating to Conductor is a rewrite of your navigation layer with no functional gain except a lifecycle you find easier to reason about.

Second, the version situation is genuinely awkward. The README states that Conductor 4.0 is "coming soon" and is already used in production, but that it is "not guaranteed to be API stable" and is therefore released as a preview. The README is careful to say that "preview in this context is not a commentary on stability" and that the preview is held to the same quality standards as 3.x. That is a reasonable position, but it still leaves you choosing between a stable line whose last release is 3.2.0 and a preview line whose newest release listed is 4.0.0-preview-4 from 2023-08-15. Neither is a fresh release.

Third, the maintenance picture deserves a direct look. The repository is not archived, and the last push was on 2026-03-14. That is recent enough that the project is not abandoned, but the release cadence and the push cadence do not match: commits are landing while the newest tagged release is years older. If your team needs tagged, documented releases on a predictable schedule, that gap is a real cost.

Finally, the README does not document rollback, migration steps from 3.x to 4.0, or a deprecation policy. The release notes are pointed to but their contents are not reproduced. That silence is itself information: plan to read the GitHub releases page before you move a production app between major versions.

## Conductor Versus Jetpack Navigation and Plain Fragments

The natural alternative is Android's own Jetpack Navigation component, which also targets single-Activity apps. The difference in approach is where the navigation graph lives. Jetpack Navigation centers on a declarative graph, usually authored in XML or in Kotlin DSL, and the framework resolves destinations from that graph. Conductor has no graph. You push RouterTransaction objects onto a Router in code, and the backstack is whatever you pushed. That makes dynamic, programmatic navigation flows easier to express in Conductor, and it makes a large app's navigation structure harder to see at a glance, because there is no single file that describes it.

The second alternative is doing nothing: keep Fragments and use the platform APIs you already know. Conductor's README argues its Controller lifecycle is simpler than a Fragment's, and it shows a lifecycle diagram at docs/Controller Lifecycle.jpg. Whether that diagram is simpler for your team is something you can judge by opening it, but the underlying claim is that Conductor removes a class of lifecycle edge cases rather than adding a new abstraction on top of them. If your Fragment code is stable, that claim buys you nothing.

A narrower alternative for the transition layer alone is to stay on Conductor but skip the extra modules: if you do not need ViewPager or ViewPager2 integration, you do not add conductor-viewpager or conductor-viewpager2, and you avoid carrying adapters you never instantiate.

## Maintenance, Upgrade Cost and the Apache-2.0 Licence

Conductor is licensed under Apache-2.0, and the repository carries a LICENSE.txt at the top level alongside CONTRIBUTING.md. Apache-2.0 is a permissive licence that includes an express patent grant, which matters for a UI framework you embed in a shipped application. It does not impose copyleft obligations on your app. This is a description of the licence text, not legal advice; have your own counsel review it if your organisation has specific requirements.

The upgrade cost is concentrated in the 3.x to 4.0 move. The README directs readers to the GitHub releases page for changes in Conductor 4, and does not summarise them. Because 4.0 is published as a preview, a team that adopts it is accepting API churn in exchange for whatever 4.0 adds. A team that stays on 3.2.0 gets API stability but will eventually have to make the same move.

There is also a lint module in the repository, conductor-lint, which suggests the project ships its own static checks. The README does not document what those checks cover, so verify that against the module's source before assuming it will catch migration mistakes.

Beyond the core, the README points to community projects, including ConductorGlide and an AutoDispose integration. The AutoDispose support is described conditionally: if the AutoDispose dependency has been added, a ControllerScopeProvider is available. Community modules are a maintenance liability you inherit, since their release timing is not tied to Conductor's.

## Conclusion

Adopt Conductor if you are building a single-Activity Android app and want navigation, backstack handling and state persistence without Fragments, and if you can pin to the 3.2.0 stable line. Do not adopt it if you depend on Fragment-specific APIs, on the Jetpack Navigation component, or on a library that expects FragmentManager to exist. Before you commit, verify three things in the repository: whether the 4.0 preview artifacts you want are published under the version string you plan to use, whether the conductor-lint module covers the checks your team needs, and whether the community modules you rely on have been updated for the Conductor version you pick. The last push to the repository was on 2026-03-14, and the newest release listed is 4.0.0-preview-4 from 2023-08-15.

## FAQ

### How do I install Conductor in an Android project?

Add the com.bluelinelabs:conductor artifact to your Gradle dependencies, using 3.2.0 for the stable line or 4.0.0-preview-4 for the preview. Optional modules cover AndroidX transition change handlers, ViewPager and ViewPager2. For snapshot builds, use 4.0.0-SNAPSHOT and add the Sonatype snapshots repository.

### How do I use Conductor in an Android app?

Attach a Router to an Activity and a container ViewGroup with Conductor.attachRouter, then set a root Controller through a RouterTransaction if the Router has no root yet. Each screen is a Controller that overrides onCreateView and returns an inflated View.

### Does Conductor replace Fragments?

Yes. The README describes the Controller as a lighter-weight and more predictable Fragment alternative, and lists single Activity apps without using Fragments as a feature. It also provides callbacks for onActivityResult and onRequestPermissionsResult, which Fragments would otherwise handle.

### What is the difference between a Router and a ControllerChangeHandler in Conductor?

A Router handles navigation and the backstack for Controllers, while a ControllerChangeHandler performs the actual swap of one Controller's View for another. The README states that Routers defer rendering to the ControllerChangeHandler specified in a given transaction, which is also where transitions and animations live.

### Is Conductor 4.0 stable enough for production?

The README says 4.0 is already used in production with many millions of users and is held to the same quality standards as 3.x, but it is not guaranteed to be API stable and is released as a preview. The newest preview release listed is 4.0.0-preview-4 from 2023-08-15.

## Sources

- [bluelinelabs/Conductor on GitHub](https://github.com/bluelinelabs/Conductor)
- [Issues](https://github.com/bluelinelabs/Conductor/issues)
- [License: Apache-2.0](https://github.com/bluelinelabs/Conductor/blob/develop/LICENSE)
- [README](https://github.com/bluelinelabs/Conductor/blob/develop/README.md)
- [Releases](https://github.com/bluelinelabs/Conductor/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/bluelinelabs-conductor
