Skip to main content

· 10 min read
Krzysztof Bielikowicz


Pearl Investment App

Dara is our open-source application framework designed for anyone who needs to turn their data and workflows into interactive, easy-to-use applications - especially data scientists, developers and decision makers. It’s designed to help people create engaging visuals and comprehensive applications without hassle.

The framework was born out of necessity; both our internal teams and our customers needed a seamless way to turn intricate work into interactive and user-friendly applications. Its development was driven by limitations found in existing solutions, where users grapple with restrictive extensibility, escalating complexity, compromised performance and challenging integrations. The current landscape made the transition from static data representation to dynamic, actionable insights a real challenge, especially for those wanting to leverage Causal AI-powered workflows.

We designed Dara to answer these problems by providing simple reusable components, a flexible and modular approach to managing application state and a smooth learning curve from your first component to a multi page application packed with interaction points.

With Dara, you can quickly build aesthetically pleasing and functionally rich applications using just Python. It also offers the flexibility for customization, allowing users to integrate custom components using JavaScript and CSS to meet their various needs.

In essence, Dara is a practical solution for those who want to present complex workflows or develop in-depth applications to support decision-making. It’s a versatile tool that helps users make sense of and act on their insights in the complex world of data-driven decision-making.

Why do we need app frameworks?

Professionals in fields such as data science or analytics frequently use Jupyter notebooks to present and share their work, models and results. These tools excel at rapid prototyping and model building phases of the workflow. However, when it comes to presenting these findings, Jupyter notebooks are unintuitive, confusing, and static for wider business stakeholders.

To bridge this gap, there exist frameworks designed to facilitate the creation of interactive web applications, enabling professionals to convey their insights more effectively. These frameworks are intended to be accessible, offering simple APIs in languages Data Scientists are familiar with, such as Python, enabling those with no experience building web applications to create intuitive and visually compelling interfaces.

Pitfalls of existing solutions

There are several popular dashboarding solutions in the ecosystem. However, when reviewing the alternatives at causaLens, we have found a few persistent issues in the design of these frameworks that stopped us from embracing what was already out there.

  • Limited Extensibility: Many frameworks offer a fixed set of components, and we needed to be able to extend the existing behaviors with our innovations.
  • Increased Complexity: Several frameworks became challenging to navigate as code complexity increased, especially when evolving from simple single-page dashboards to multi-page applications with intricate interactions.
  • Compromised Performance: The performance of some frameworks was severely hampered by their dependency to call back to the Python code for even the simplest update or interaction, often requiring full page refreshes.
  • Challenging Integration: Some dashboarding frameworks posed integration challenges, making it cumbersome to add REST endpoints for automated processes to access the same functionality as the dashboard without implementing multiple solutions.

Our solution

As a result, we set out to build our own application framework to solve these challenges. We needed something that worked for us and our customers. These were our guiding principles:

Native Causality Support

We believe that Causal AI tech is a foundation to empower informed decision making through explainable causal models. In order to interact and explain Causal Models we have built a set of components that let you visualize, tweak, and explore them. They allow decision makers to interact with complex technology in a simple and user-friendly way.

Discover the capabilities of our graph viewer component. We’ve also open-sourced a complementary casual graph library to assist in defining and working with causal structures. We invite you to experience and explore these tools, developed to support the visualization and exploration of intricate causal relationships.

Graph Viewer Gallery App

Graph Viewer showcase gallery app

Smooth learning curve & scalability

Dara provides a gentle learning curve, allowing users to progress from creating basic dashboards with no user interaction to developing intricate, multi-page applications featuring numerous interaction points, all while maintaining clean and manageable code.

When you’re just starting with Dara, creating your first app is quite straightforward. Here’s how you can create a simple ‘Hello World’ in Dara:
from dara.core import ConfigurationBuilder

# Initialize app config, using builder pattern
# to build up the app piece by piece
config = ConfigurationBuilder()

# Add a single page at /hello, with the text 'World' on the page
config.add_page(title='Hello', content='World')

Hello World App

Simple ‘Hello World’ in Dara

On the flipside, if you’re a seasoned developer, know that Dara can handle the heavy lifting - the framework has been thoroughly tested by our internal team, running multiple multi-page complex web apps in production.


In Dara, components are the heart of your application. Think of them as reusable pieces of UI that act as building blocks. You can arrange, modify, and integrate these blocks wherever needed within your app, making application design both efficient and structured.

Now, the foundation of Dara lies in its core – the dara-core. This core is responsible for the fundamental architecture of the framework. It provides the scaffolding and essential utilities that enable all other functionalities. While dara-core lays the foundation with essential abstractions and interactivity primitives for application development, it doesn't come bundled with a comprehensive set of user interface elements.

That's where libraries like dara-components step in, offering a rich set of ready-to-use components that are built on top of the core's abstractions. This module is built upon the sturdy abstractions provided by dara-core and offers a vast library of pre-designed components. It's like the toolkit that equips you with everything you need to construct a full-fledged application. To showcase its potential, let's revisit our previous example and add a Text component:
from dara.core import ConfigurationBuilder
from dara.components import Text

config = ConfigurationBuilder()

# Add a single page at /hello, with the text 'World' on the page
config.add_page(title='Hello', content=Text(text='World'))

The best part is - you can create a multitude of components by leveraging the existing building blocks Dara provides, all without needing any knowledge of JavaScript. Function-based (or class based, depending on your preference) components in Dara allow you to encapsulate and reuse logic, making your applications more modular and maintainable. You can piece together these components like building blocks, orchestrating them to create intricate, fully-fledged applications.

Here's a brief example of how you can compose a component using a function:
from dara.core import ConfigurationBuilder, SideEffect
from dara.components import Button, Stack, Text

def GreetingPanel(name: str):
greeting_text = Text(text=f"Hello, {name}!")
greet_button = Button("Greet", onclick=SideEffect(lambda: print(f"Greeted {name}")))

return Stack(greeting_text, greet_button)

config = ConfigurationBuilder()
config.add_page(title="Greet", content=GreetingPanel("John"))

Example of creating a reusable GreetingPanel component in Dara

In this example, GreetingPanel is a custom component created by combining Text and Button components, demonstrating how easily existing components can be composed to create new ones. Using this approach, you can create comprehensive and interactive applications, mastering the art of component composition before deciding to delve deeper into JavaScript for more advanced customization.

Remember, writing custom components in JavaScript is entirely optional in Dara. Most users find that the extensive set of built-in components, combined with the power of function-based composition, fulfills their needs, making the transition to creating applications smooth and enjoyable.

Once you understand how to incorporate components into your applications, you might be curious about how components are constructed in Dara. Components are essentially ComponentInstance subclasses, mapping its class properties to a React component.

Python Definition (dara.components/
from dara.core.definitions import ComponentInstance

class Text(ComponentInstance):
js_module = '@darajs/components'
text: str
TypeScript Implementation (@darajs/core/index.tsx)
interface TextProps {
text: string;

export function Text(props: TextProps) {
return <p>{props.text}</p>;

Simplified implementation of a Text component

This simple but powerful abstraction is the foundation upon which the dara.components library is built upon, and how you can also choose to write your own components.

After understanding how to integrate and construct components, it’s essential to explore how Dara supports further customization. The ConfigurationBuilder instance is your gateway to a plethora of customization options, allowing you to tailor your projects according to your evolving needs. From integrating authentication configurations, registering custom components, and themes to additional HTTP endpoints, Dara ensures your projects can grow in complexity without compromising structure or maintainability.

This unified interface enables the straightforward distribution of reusable plugins, even beyond the core framework. Here’s a snippet showcasing the integration of a custom plugin:

from dara.core import ConfigurationBuilder

def custom_plugin(config: ConfigurationBuilder):
# ...
from dara.core import ConfigurationBuilder
from some_package import custom_plugin

config = ConfigurationBuilder()

Example of a custom Dara plugin

With Dara, it’s not just about starting simple; it’s about scaling and extending your projects effortlessly, no matter how complex your needs become!

Plot Interactivity App

Plot Interactivity Dara gallery app

Close to native web-app performance

To ensure scalability, our architecture is designed with reducing the client-server back-and-forth in mind. Therefore, state updates happen mostly in the browser. Your application will only call into the Python side when absolutely necessary.

For instance, if you’re just connecting an Input component to a Text component, there’s no need to involve your server; the data never leaves your browser.

Variable data flow

Data flow with a simple Input->Text synchronization; update happens without server interaction

In situations where you need to run calculations based on user input, the framework is smart—it only pings the server for that specific calculation while the rest of the rendering stays client-side.

Derived Variable data flow

Data flow involving a derived computation result; update happens in the browser, a single request is made to the server for just the computation result

We’re just scratching the surface with these diagrams. They offer a glimpse into the architecture which powers Dara.

Support hybrid access modes

As we touched upon earlier, our framework streamlines the process of defining and adding REST endpoints through a simplified API. Here’s how:
from dara.core import ConfigurationBuilder
from dara.core.http import get

# route definition, can be anywhere in your app or an external package
async def hello_route(name: str):
return f'Hello, {name}!'

config = ConfigurationBuilder()

# register the route in your app

Example of registering a custom route in a Dara app

This makes it simple for automated processes to consume some of the business logic presented in your dashboard. The routes added are covered by the authentication system (which you can opt out of), making your app secure by default.

And for those familiar with FastAPI, you’ll find the API quite intuitive—under the hood, it’s all FastAPI, making the learning curve even smoother.


Dara was created with everyone in mind: from data scientists to developers and decision-makers. We recognized the challenges faced when trying to turn complex data into easy-to-use applications, especially when AI comes into the mix. Dara is our answer to those challenges. It focuses on practicality, aiming to provide a smoother and more intuitive experience in implementing AI to facilitate informed decision-making processes.

With Dara, our goal is to offer a clear, accessible, and adaptable framework. We've shared a glimpse of what Dara can do, and we are eager to delve deeper and share more about its capabilities and how it stands out in our upcoming posts.

· 10 min read
Patricia Jacob
Seojin Park


The purpose of this blog post is to guide you through the typical stages of app design, whether you're an engineer or a data scientist. In this guide you will walk through a step-by-step building process of creating a user-friendly app. In the world of technology, effectively presenting your work to stakeholders is a fundamental practice. A basic understanding of design allows bridging the gap between technical expertise and stakeholder communication, and giving your work a distinctive edge that resonates with both functionality and appeal.

For data scientists

As a data scientist, your skills to collect, process, and analyze data and to train sophisticated models provide valuable insights that guide key stakeholders towards making the right decisions. However, you might often face challenges in effectively communicating these results. Relying on static documents may fail to showcase the full potential of your models and to captivate the interest of business users. Nothing can be more frustrating than your work not being utilized to its maximum potential. This is where a dynamic, interactive application comes into play. It transforms your work into a living tool, inviting stakeholders to an environment of exploration, collaboration, and real-time decision-making.

For engineers

As an engineer, your role is central to translating ideas and requirements into functional and efficient applications, building interfaces that users interact with, and ensuring that technology serves its intended purpose seamlessly. By having a foundational understanding of design principles, you not only enhance coding skills but also become a part of a process that's about building tools that empower decision-making, exploration, and real-time engagement with data.

Dara is here to help

Dara is an application framework that enables you to build visually appealing and interactive web applications. It provides prebuilt components that can be easily put together in Python. With Dara, you can showcase your creation and communicate outcomes effectively overcoming the gap between technical and non technical users.

From an idea to design

This blog will guide you through the process of designing an interactive app which can be adapted and followed in any context to promote user-friendliness.

Suppose you are a data scientist at the company “Pearl Investment”. With the available data, you developed a fantastic model to identify new customer leads and retain current ones. Now, it’s your time to show it off - but how?

Define the application goals

Firstly, it's vital to ask, "Why go through the effort of making an app at all?" It's essential to define the goals before diving into the process. Here are some guiding questions:

  • What problem is your app addressing?
  • How does it add value to your users?
  • What are the key takeaways from your app?

Once you understand your user’s goals, then the purpose of the app becomes clear. At this stage, you don’t have to think about features and designs. Remember, clarity of purpose is key when it comes to creating a useful and successful app!

The user wants to know whom they should call from a vast listRecommend potential new customers
The user wants to identify who is at risk of leaving and what strategies can retain themSuggest retention strategy for existing customers
The user wants to ensure the model is trustworthyDemonstrate the model's reliability and accuracy

Identify your users

Next steps are to define the user(s) of the app, the cornerstone of user-centred design. An understanding can be built through methods ranging from market research and brainstorming to casual discussions over a cup of tea. For instance, at Pearl Investment, Sales Managers could benefit from the app's predictive model to strategize their daily communication tasks, determining whom to call or email.

User TypeCharacteristics
Sales manager- Not very technical
- Prefer conventional plots and text explanation
- Need prompt actions everyday
- Care about model performance and explainability

Planning the app structure and features

Having outlined what the app is, its purpose, and its intended users, our next step is to visualize the user journey. It is crucial for you to understand how users will navigate through the app and what pages they'll need to fulfil their objectives.

If the app is complex, it is effective to have separate pages in a natural order and present relevant contents together to reduce the cognitive burden of the user. And Dara provides a template where you can easily put contents into several pages. One way to facilitate this process is to visualize a typical user's journey through the app:

  • Opening the app, the first thing I view is the candidates.
  • I click on a specific candidate to get a detailed analysis.
  • I identify customers likely to churn on a separate page.
  • I set the restriction based on reality and get a retention strategy.
  • I explore a detailed analysis of the suggestion.
  • I want to check how trustworthy the model is with visual and text explanations.

Now the idea on what features are needed and where it should be placed becomes more tangible. This can turn into a brief “spec” of an app like the table below. Remember, it's entirely natural to make adjustments to this structure as you add and refine features. Just make sure the pages follow a logical hierarchy and the user journey stated above.

Customer Leads- A list of customer leads with scores.
- Filter and sort to identify specific customers.
- Various action buttons such as call, email, and integration with salesforce.
- Modal to explain why this customer has this score with data distribution.
Customer Retention- A list of customers with churn probability.
- A panel to adjust constraints for intervention.
- A result panel to show possible intervention.
- Modal to explain why this intervention was suggested with plots.
Model Explanation- Show a causal graph and explain nodes and edges for the Customer Leads model.
- Show a causal graph and explain nodes and edges for the Customer Retention model.

Each feature requires relevant inputs and outputs, therefore, it is important to examine available resources and additional resources required to turn this vision into reality. This involves asking questions like "What information needs to be displayed to the user?” and “What inputs are needed from the user to bridge the gap between our available resources and the information they need to see?” For example, if you were to develop a generic customer cycle management app for any investment firm, you might need to include a feature allowing users to upload their own datasets into the app.

Drawing a wireframe

Now you have all the ingredients to visualise and put into a design or a “wireframe”. Wireframes serve as the blueprints of an app, providing a visual representation of its layout and functionality. The temptation to dive headfirst into coding might be high, but allocating time for sketching or planning can be incredibly beneficial. The advantages of wireframing are manifold: it facilitates swift iteration between various designs, aids in aligning team ideas and vision for an app before extensive coding efforts, and once completed, it can be broken down into manageable components to enhance app structure and maintainability.

Creating wireframes doesn't have to be a complex process; they can be as simple as rough hand-drawn sketches, effectively and swiftly bringing your ideas to life. For those preferring digital tools or seeking a straightforward interface, Excalidraw serves as an intuitive choice. For more experienced users seeking advanced features, tools like Figma are worth considering. The choice between these methods hinges on your comfort level, expertise, and the project's unique requirements.

Example of the customer leads page with a list of potential customers and leads score. Showing a hand drawn and Excalidraw interpretations.

Hand DrawnExcalidraw
Hand DrawnExcalidraw

Customer retention page with a list of existing customers and possible actions for retention. Hand Drawn

Modal for individual results explanation Hand Drawn

Model explanation page that showcases the model behind the suggestions. Hand Drawn

From design to an app

In this section you will go through the next step, converting the idea into an actual app. Depending on your coding style you may want to jump right into it. However if you are unsure you could always make a "shell app", that is add the components to the page without worrying about functionality.

Try a shell app

Shell apps allow for quick iteration of design, without having to worry about underlying logic. They are purely there to give you an idea of how an app might look like. This approach can also be quite useful in allowing you to see repeating patterns and help to structure your app without the extra layer of complexity that interactivity adds.

Customer Leads Customer Retention Modal 1 Modal 2 Model Explanation

Run user testing

To ensure that your app really serves its purpose, it is crucial to test it with the user throughout the entire process. By doing so, improvements can be found and implemented gradually, not having to be fixed at the last moment. There are numerous ways to test an app based on the development phase. For example, tests can be done even before anything is coded by simply asking the users for their thoughts while showing the wireframes. When a concrete artefact such as a shell app is available, thinking aloud is a great method to check usability. Thinking aloud is very easy to conduct and can collect rich data in a short period of time. Like this, conducting iterations of tests and improvement can enhance the quality of the app drastically.

Build with Dara

Now it’s the time to build your app with Dara! Dara provides various components which you can easily assemble using only python. The result is this beautiful, informative and interactive app. Stay tuned for an upcoming blog post where we will take you through the steps into making this a reality.

App1 App3 App2


In this deep-dive, you've navigated the complex yet rewarding process of designing a user-friendly app that offers insights to stakeholders interactively. Our journey began with identifying clear goals, understanding our users, and outlining our pages with relevant features. Then, the journey continued to sketch out plans with wireframes which can be brought to reality with Dara.

Remember, the processes discussed aren't necessarily linear and can be approached in any order. They can be adapted or even omitted based on your available resources and time. What's important is discovering a method that resonates with you and your team, and tailoring it to suit your unique needs.

· 2 min read
Claudia Westby
Krzysztof Bielikowicz
Patricia Jacob
Sam Smith
Seojin Park
Tamara Stemberga

About Dara

At causaLens, we've set our sights on an exciting mission: creating decisionOS, a platform that empowers organizations with trusted, collaborative, and actionable decision-making powered by Causal AI.

To bring our vision to life, we've been scouting some cool application frameworks. Our aim is to highlight our causal tech in a simple and interactive way while offering actionable insights. We wanted something that would allow us to build performant low-code web apps which:

  • have the capabilities to visualize and explore the data structures via Causal Graphs
  • are easy to use and maintain by Data Scientists and Engineers alike
  • are customizable, extensible and scalable
  • can be easily integrated with our existing tech stack

The outcome is Dara, a dynamic application framework designed for creating interactive web apps with ease, all in pure Python. Dara has fueled the development of hundreds of apps, now widely used and appreciated by both our customers and our in-house teams!

Dara, which signifies "pearls of wisdom" - we hope that Dara will help you build your own shiny apps!

The Team

Dara is maintained by a diverse team of engineers with different backgrounds and experiences. We are passionate about building great products and we are excited to share our journey with you!