Trying Shorebird. Project setup and feature set

Andrii Khrystian
7 min readSep 25, 2023

What do you know about CodePush in Mobile Development? The obvious explanation for this term is when developers can push their code somewhere. But where? In this exact case, developers can push code directly to users, without uploading anything to the Developer Console. And end users will receive this update immediately. This sounds great, as in fact, now we would need to go through submission hell.

What are the use cases? So, we as developers sometimes make mistakes, and we have something called incidents (even in Mobile Development), and we would need to fix this ASAP. At this point CodePush can be really useful.

Are there already any examples? The only thing that comes to my mind is React Native. Yes, React Native guys have had this feature for a while, and it has always been one of the points where RN developers can say that RN is better than Flutter. According to this graph, this feature has been in RN for ages.

But time flies, and now Flutter is more commonly used as a cross-platform solution. Flutter developers, as well as product managers, require CodePush in Flutter. And now, please welcome Shorebird.

What is Shorebird?

First of all, Shorebird is a product designed for individual developers and companies, enabling them to create code pushes directly to end-user devices. The creators of Shorebird are well-known and reputable figures in the Flutter Development world. This fact personally instills a high level of trust in this product for me.

When and why should we use Shorebird?

For example, you or your team might encounter a significant issue — such as a crash on startup or a problem with the API — that is causing your product to lose customers and revenue. The standard process of releasing an application takes time, including the necessary review processes. However, Shorebird can deploy a hotfix in seconds. Shorebird serves as a valuable safety net for your product.

Implementation and Feature set

In order to install Shorebird you just need to run one single command

curl --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/shorebirdtech/install/main/install.sh -sSf | bash

And after successful install you would need to execute login command

shorebird login

After successfully logging in, the next step is to initialize Shorebird within our Flutter project. I have an existing project called “Todo,” and I’ll demonstrate how to set up Shorebird within this project.

After calling “init,” we need to confirm the name of the project, which in my case is “todolist.” But what does this command actually do?

  1. It creates a specific configuration file called shorebird.yaml. This file contains app-id and auto_update options.

2. It includes shorebird.yaml as an asset inside pubspec.yaml.

3. Finally, it adds Internet Permission to the AndroidManifest of your project if it’s not already there.

Additionally, this command creates a project in the Shorebird developer console, which looks like this:

So now looks like we are ready for our first release. So we just need to execute release command.

shorebird release android

The result of this command looks like this

As you can see this command creates a bundle ready to be uploaded to Google Play, besides it creates an app release on Shorebird console.

The version of the release is taken from pubspec.yaml, so you can obviously customize it.

After we’ve made a release, we should run the preview command to be able to simulate the Flutter app’s behavior. To make it more clear, let’s remove the existing app from the device as well.

shorebird preview android

And here is the result

This command downloads the artifact from the Shorebird console and installs it on the device (Android in our case). Our screen looks like this:

Release version of the app

Oh no, I discovered that I have a HiveError, for the box which is closed:

 E flutter : [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: HiveError: Box has already been closed.
: #0 BoxBaseImpl.checkOpen (package:hive/src/box/box_base_impl.dart:76:7)
: #1 BoxImpl._writeFrames (package:hive/src/box/box_impl.dart:83:5)
: #2 BoxImpl.putAll (package:hive/src/box/box_impl.dart:67:12)
: #3 BoxBaseImpl.put (package:hive/src/box/box_base_impl.dart:104:45)
: #4 HiveObjectMixin.save (package:hive/src/object/hive_object.dart:36:18)
: #5 LocalDataSource.updateTodoItem (package:todolist/repo/datasource/local_data_source.dart:52:16)
: <asynchronous suspension>
: #6 TodoListBloc._completeItem (package:todolist/blocs/todos/todo_list_bloc.dart:28:5)
: <asynchronous suspension>
: #7 Bloc.on.<anonymous closure>.handleEvent (package:bloc/src/bloc.dart:229:13)
: <asynchronous suspension>

And this is the moment for Shorebird to shine. I know how to fix this error, and the error is fixed locally. Now, I need to patch my existing release to deliver this fix to end users. In order to do this, I need to execute the patch command:

shorebird patch android

And here is the result

➜  todo git:(main) ✗ shorebird patch android
✓ Fetching apps (0.4s)
✓ Building patch (32.6s)
✓ Detected release version 1.0.0+1 (0.3s)
✓ Fetching releases (0.3s)
✓ Fetching release artifacts (0.6s)
✓ Fetching aab artifact (0.2s)
✓ Downloading release artifacts (4.0s)
✓ Verifying patch can be applied to release (3.1s)
✓ Creating artifacts (5.6s)

🚀 Ready to publish a new patch!

📱 App: todolist (87b5ccf1-b86f-427b-8df8-2ca70e8ba4a3)
📦 Release Version: 1.0.0+1
📺 Channel: stable
🕹️ Platform: android [arm64 (101.61 KB), arm32 (97.19 KB), x86_64 (110.58 KB)]

Would you like to continue? (y/N) Yes
✓ Creating patch (0.2s)
✓ Uploading artifacts (2.7s)
✓ Fetching channels (0.2s)
✓ Promoting patch to stable (0.4s)

✅ Published Patch!

After refreshing the app on device error disapears. But this change is not really visible for the end user. Let’s change some texts and colors. I made two patches for that. Here is the end result

And remember: I didn’t re-install the app! Isn’t this cool? I’m sure it is. Btw this is how shorebird console looks like now:

Unfortunately, as of September 25, 2023, no analytics are available. But I’m certain that this feature has been requested and will be available sometime in the future.

What if I release a broken patch that crashes the app on startup? Shorebird is smart and it will not allow you to release such a patch. In case you insist and your app does crash, Shorebird will roll back your app to the previous patch.

Pitfalls

1. Under the hood, Shorebird is using a custom interpretation of Flutter, and as of September 25, 2023, there are some performance issues on iOS. That’s why the iOS version of Shorebird is still in Alpha.

For some larger products, this could be a significant concern. However, the development team has made it a high-priority task to stabilize the iOS version, so I’m confident that it will be resolved soon.

2. At this moment it’s not possible to include assets to your patches.

3. It’s not possible to do native code updates. So this means that you can’t add/update your plugins, or do any possible changes within your native code.

4. Lack of functionality on console side. It’s always nice to see some heads ups about your patches and releases.

Pricing

Oh it’s not for free of course. The job which was done is already remarcable (You can check the source code on github), so it couldn’t be fully free.

Besides, it offers a Hobby option. It’s important to mention that the 5k limit refers to patch installs, not the number of patches themselves. So, if you have 5k active users and you release one patch, your plan is exhausted for the month.

What’s crucial is how you use Shorebird. If you make significant changes to your app every day or release patches for every minor bug without testing, it could become an expensive option. Shorebird is more about safeguarding your product and providing insurance against incidents

Conclusion

Shorebird is a nice tool, which is still in active development phase. I would definitely recommend to add shorebird to your projects after iOS stable release.

Happy coding!

--

--