August 31, 2022

How Bloom Housing’s Technical Architecture Can Adapt from Regional to Independent Systems

In the last year, Exygy’s Bloom Housing engineering team has adapted and learned how to develop in two different modes: regional and independent systems.

Bloom Housing is proud to be an open source affordable housing platform. Exygy’s team of engineers maintain a core repository which others, including civic entities, may fork to develop independently. Our team maintains two of these forks: one for the San Francisco Bay Area, and the other for the City of Detroit. 

One of the greatest challenges that the Bloom Housing engineering team has met over the past year was adapting to and learning from two different modes of development: 

  1. A regional system, where multiple cities and counties are joint stakeholders, and 
  2. An independent system, where the platform only has to meet the needs of one jurisdiction. 

In this blog, we provide an overview of these two pathways and share out some of our learnings along the way.

Configuration Over Customization for Regional Systems

Bloom Housing was built to accommodate the many jurisdictions that reside in the San Francisco Bay Area, such as the City of San José and Alameda County. This multi-tenant system allows different civic entities to configure their listings and application process to align with the area's housing policies without any code changes. This model has worked well for the Bay Area, because there have not been considerable differences in what data the housing portals present and how they want to present it. With the differences that do exist, such as different options around housing programs and AMI (area median income) charts and features that allow users to sign up for notifications, we are able to keep them all in the same system through jurisdictional configuration settings and how Bloom maintains relationships between different data models.

When a jurisdiction requests a feature, the Bloom team evaluates that feature for use with other jurisdictions. This informs us in how we configure all or parts of the feature. We often find that some or all of the jurisdictions want the same feature, but not on the same timeline. This is easily solved by adding a setting that the system reads by jurisdiction, so we can enable features when the client is ready.

The challenge in developing a feature is in finding the balance between what can and cannot be true for all stakeholders. Making every part of the feature configurable may be future proof, but is it necessary? Most of the time, adding a minimal amount of configuration and favoring iteration has been the path forward. More configuration and variables commonly result in a longer turn-around between feature request and launch, due to requiring more stakeholder engagement and a longer development period. This also leads to more vectors to account for in testing and quality assurance.

While more considerations have to go into development, deployment of features in the multi-jurisdiction model can be more streamlined, since the portals all share the same backend. However, if a public site has customizations we have to ensure these updates do not cause regression issues. Creating more configuration to remove the need for any customization is the path the team wants to take, at least in the Bay Area.

More Flexibility for Features with Independent City Systems 

In 2021, Bloom Housing began to expand outside of the Bay Area, which allowed the team to experiment with a different development and deployment model. Introducing other cities on separate systems, using the same Bloom core as the basis, allows us to be more flexible in how we develop features. In this model, we can develop features independently for a jurisdiction, which allows us to develop more quickly for a specific jurisdiction and let us take our time in designing how, if applicable, the feature can be rolled back up into Bloom’s core set of features.

This came into play in developing Bloom for the City of Detroit. Detroit already had a large set of affordable housing listings that could be curated and imported into the system. As the team began to evaluate this set of data, it became clear that changes to Bloom's data models would make it easier for housing developers in the Detroit area to edit and input new data. One of the larger pieces of Bloom that required change was around the handling of units for a listing (think one bedroom on the second floor and two bedrooms on the first). In the Bay Area, units are configured individually, so if a listing has eight units the housing developer must enter in the data for each individual unit. This allows for a high level of granularity. There are also copy/clone features in the portal to aid in this endeavor, but it can become tedious, especially if all a housing developer really wants is to provide a summary of the units available for a listing.

A screenshot of the City of Detroit’s new unit summary page, which can be included as a feature option for any future jurisdictions who implement Bloom Housing.


The City of Detroit's affordable housing data did provide more of a summary of its units per listing and because the implementation is not tied to other jurisdictions, the team was free to create a unit summary model and in a short amount of time. Now, housing developers in the City of Detroit are able to add multiple unit groups to a listing. A range of settings can be configured for each group, from number of bedrooms, occupancy and square footage, to multiple AMI levels with different ranges of affordability.

This feature was necessitated by the limited data available, but the team sees value in adding it to the core set of available features. Now that we have a design and implementation of what a summary of units can look like, the team can think about how we can bring that concept back into the Bloom Housing core repository and from there apply it to other jurisdictions.

Moving Forward with Both Models

A clear benefit emerged out of the regional system: the multiple data points and feedback that each jurisdiction provides can help us build more informed and scalable systems. This more closely models how we want to continue to develop features for the core product.

The independent city system allows us to be more flexible in our feature iterations, before bringing a feature into the core system. This model also serves as an example of how a member of the open source community can fork Bloom’s code and develop features that meet their jurisdictions needs, all while keeping in sync with the core system, so when ready and with Bloom team’s guidance, they can contribute their work back for everyone’s benefit.

We look forward to continuing to iterate and expand on this model, and to growing the community that supports Bloom, which in turn will help grow its accessibility so that civic entities of all sizes can provide a means for the public to find and apply to affordable housing.

What’s a Rich Text element?

H1 example

H3 example

The rich text element allows you to create and format headings, paragraphs, blockquotes, images, and video all in one place instead of having to add and format them individually. Just double-click and easily create content.

Static and dynamic content editing

A rich text element can be used with static or dynamic content. For static content, just drop it into any page and begin editing. For dynamic content, add a rich text field to any collection and then connect a rich text element to that field in the settings panel. Voila!

How to customize formatting for each rich text

Headings, paragraphs, blockquotes, figures, images, and figure captions can all be styled after a class is added to the rich text element using the "When inside of" nested selector system.

Sean Albert
Engineering Director

Want to work together?

We are always looking to get in touch with partners to help build healthy and resilient communities together
contact us