git ssb


Daan Patchwork / manyverse

Tree: fa5d67a73d5314da4fb469ac62ed0318b761f463

Files: fa5d67a73d5314da4fb469ac62ed0318b761f463 /

14201 bytesRaw

Contributor docs

Installation and dev setup

This project uses React Native, Android SDK, Node.js and NPM.

React Native specifics

Use node ^10.13.0 and npm ~6.4.1, and follow the official React Native docs.

Also install the CLI:

npm install --global react-native-cli

macOS specifics

If you are developing on a macOS, then you might need realpath, install it through coreutils:

brew update
brew install coreutils

Android specifics

You need Android Studio and a recent Android SDK (installable through Android Studio).

You may need to open your app's /android folder in Android Studio, so that it detects, downloads and cofigures requirements that might be missing, like the NDK and CMake to build the native code part of the project. OR download those via the sdkmanager $ANDROID_HOME/tools/bin/sdkmanager 'ndk-bundle' 'cmake;3.6.4111459'.

You can also set the environment variable ANDROID_NDK_HOME, as in this example:

export ANDROID_NDK_HOME=/Users/username/Library/Android/sdk/ndk-bundle

Also check out nodejs-mobile repository for the necessary prerequisites for your system.

This app only supports Android 5.0 and above.

Manyverse specifics

npm i

Build and run in development

You can run npm run build-android-debug which will run all the necessary scripts in order. Or run each step manually:

1: Compile TypeScript files

npm run lib

2: Propagate replacement modules throughout all dependencies using propagate-replacement-fields:

npm run propagate-replacements

3: Build the "backend" Node.js project (which runs ssb-server):

npm run build-backend

4: Build the Android apk:

react-native run-android

During step 5, another terminal may spawn with the React Native Metro bundler. The app should be installed automatically, if you have a device connected by USB. You can see the logs with react-native log-android or adb logcat.

Continuous compilation

To watch source code files and continuously compile them, use three terminals:

There is no support for continuously compiling the backend Node.js project.


On Android applications, the react-native build process is sometimes unable to rebuild assets. If you are getting errors while building the application using react-native run-android, then the command npm run full-clean can help you do a clean rebuild of the project. Then, reinstall with npm i and rebuild.

app:installDebug FAILED - Could not find build of variant which supports .. an ABI in x86

ManyVerse only supports ARM architectures, but most virtual device emulators use an x86 architecture of the host computer, and are therefore not supported.

Debug your code using a 'real' mobile device connected over USB instead.

NullPointerException on npm run build-backend

If you see the error below while running the build-backend build script, you should try opening this project's android folder in android studio (using the build.gradle file to tell android studio it is a gradle project.) It should detect missing dependencies and give you the option to install them via the console window (and rebuild) at the bottom of the window.

Building native modules for armeabi-v7a...
Incremental java compilation is an incubating feature.

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring project ':app'.
> Could not resolve all dependencies for configuration ':app:_debugApk'.
   > A problem occurred configuring project ':nodejs-mobile-react-native'.
      > java.lang.NullPointerException (no error message)

Issue labels

For every issue, pick a type, a scope, and a priority:

There's also a rule for priority labeling: must < should < could < maybe. In other words, the number of must issues has to be less than the number of should issues, which has to be less than the number of could issues, etc. This gives a funnel shape to the kanban board, see here.

Ideally, in a team of N developers working on Manyverse, there are N issues marked work in progress. In the "must" column, there are usually 2~4 issues per developer, which means at any time I choose the next work to do, I only have to pick one issue out of three, approximately. I try to keep a somewhat golden ratio progression (i.e. more than 1x, less than 2x multiplication) to the shape of the funnel, but it doesn't need to be so strictly organized. The importance of organizing the issues is also proportional to the priority:

Once in a while, as issues get done, we go through the issues in lower priorities and begin promoting them to higher levels. You can think of this funnel as a job interview process with multiple stages of interviews. We try to imagine which of these issues "earns its spot" the best. And usually give priority to fixing bugs, because it's worth building new features after the current user experience is mostly bugless. But every month there should be at least one new feature, even a small feature suffices.

This funnel shape also works for the Feature roadmap, which is kind of like a backlog, but less actionable, it's basically a backlog of ideas, while the issues are a backlog of tasks to perform as a developer.

Then there are less important issues, that are used just for communication:

Codebase overview

The app is built on these technologies:

There are three important parts to the app, executing in runtime as different threads: frontend thread handles UI logic for the features, backend thread handles local database and peer-to-peer networking capabilities, app thread lightly coordinates the lifecycle of the app and creation of the other two threads.

|         FRONTEND THREAD         |
|                                 |         +----------------------------------+
|   TypeScript  (dev language)    |         |            APP THREAD            |
|   JavaScript  (target language) |         |----------------------------------|
|     Cycle.js  (framework)       |<------->|                                  |
| React Native  (JS runtime env)  |         |            Java  (language)      |
| src/frontend  (path to src)     |         |     Android SDK  (framework)     |
|        8000+  (lines of code)   |         |    React Native  (framework)     |
+---------------------------------+         | android/app/src  (path to src)   |
                                            |            150+  (lines of code) |
+---------------------------------+         |                                  |
|         BACKEND THREAD          |         |                                  |
|                                 |<------->|                                  |
|   TypeScript  (dev language)    |         |                                  |
|   JavaScript  (target language) |         |                                  |
|   ssb-server  (plugin system)   |         +----------------------------------+
|      Node.js  (JS runtime env)  |
|  src/backend  (path to src)     |
|         300+  (lines of code)   |

Most app development happens in src/frontend and thus follows the Cycle.js architecture, but utilizes React Native components for rendering. It's good to get familiar with the architecture, but here is an explanation of it in a nutshell:

Integration tests

We use Appium and Tape, just plug in a device through USB and run npm run test-e2e-android. This will run tests on top of the release variant of the app, so it that doesn't exist, you must run npm run build-android-release first.


To build a release APK, follow these instructions, in short:

  1. Put the correct file my-release-key.keystore in the folder android/app/
  2. Configure the file ~/.gradle/ with the correct values
  3. Run cd android && ./gradlew assembleRelease (just builds the APK) or npm run release (for official releases)


After npm run release runs, it will update APK files in two folders: ../dat-release-all and ../dat-release-latest. The following steps should be done manually (until we automate this):

Built with git-ssb-web