What we build with, and why each thing.

This isn't a list of trends or pretty logos: it's the exact stack our four products are built and running on. Next to each technology we tell you which product we use it in and why we chose it — because choosing wrong here costs you for years.

01 Stack by product

Four products, two ecosystems.

We're not a one-technology shop. We work deeply in .NET and Node, and we choose based on the problem and on the team that will maintain the system afterward — not on what's most comfortable for us.

Each product's real stack
Product Backend Frontend Mobile Database
ResiHub NestJS · TypeORM React · Ant Design React Native · Expo PostgreSQL
Billium ASP.NET Core · Clean + CQRS Next.js · Tailwind PostgreSQL
Cliento CRM NestJS · TypeORM React · Ant Design · Vite PostgreSQL
TalentUs ASP.NET Core · EF Core Angular · Material SQL Server

.NET ecosystem 2 products

When the client already lives in Microsoft, when SQL Server is involved, or when the internal team that will inherit the system codes in C#.

  • Strong typing and a compiler that catches a lot before production.
  • Entity Framework Core with solid migrations.
  • A mature ecosystem for the boring but critical stuff: X.509 digital signing, XSD validation, background jobs.
  • It's what powers Billium's DGII conformance.
  • ASP.NET Core
  • C#
  • EF Core
  • SQL Server
  • Hangfire

Node ecosystem 2 products

When a mobile app is involved, when real-time is needed, or when it helps for backend and frontend to share types and language.

  • One language from the database to the app: TypeScript all the way.
  • NestJS imposes structure and holds up a system covering 61 management areas.
  • Real-time with Socket.io without fighting the framework.
  • Shares types with React and React Native.
  • NestJS
  • TypeScript
  • TypeORM
  • PostgreSQL
  • Socket.io

02 Backend

Where the business logic lives.

It's the part no one sees and the one that decides whether the system holds up. Here we don't experiment: we use mature frameworks, with imposed structure, that another team can pick up.

ASP.NET Core

The compiler catches whole classes of errors before they reach production. Unbeatable for the critical and boring: X.509 digital signing, XSD validation and cryptography.

Used in Billium TalentUs

NestJS

It imposes a modular structure from day one. It's what lets ResiHub have 61 management areas without turning into a plate of spaghetti.

Used in ResiHub Cliento

TypeScript

Strict

Everything that runs on Node we write typed. The type that defines an invoice is the same in the backend, in the dashboard and in the mobile app.

Used in ResiHub Cliento Billium

Clean Architecture

Pattern

Business rules don't depend on the database or the framework. Switching providers doesn't force you to rewrite the domain.

Used in Billium TalentUs

CQRS

Pattern

Separating reads from writes. In invoicing it matters: issuing a receipt and querying it have completely different requirements and risks.

Used in Billium

JWT + Passport

Auth

Access token and refresh token, with real revocation: deactivating a user or suspending a tenant cuts the active session, not on the next reload.

Used in ResiHub Cliento Billium TalentUs

Socket.io

Messages and notifications that arrive without a refresh. The chat between resident and management runs on this.

Used in ResiHub

Hangfire

Jobs

Background jobs with retries and a control panel. It checks receipt status against the DGII and cleans up expired tokens.

Used in Billium

Scheduled cron

Jobs

17 scheduled tasks in ResiHub and 3 daily in Cliento: flag overdue invoices, remind follow-ups and alert on stalled opportunities.

Used in ResiHub Cliento

03 Frontend

Dashboards used eight hours a day.

An admin dashboard isn't a landing page: it has tables of thousands of rows, long forms and users who know it by heart. You optimize for speed of use, not first impression.

React

The foundation of three of our four dashboards. A huge ecosystem, and finding someone to maintain it later is never a problem.

Used in ResiHub Cliento Billium

Next.js

App Router, with public routes and authenticated area separated. Server rendering where SEO and first load matter.

Used in Billium

Angular

Opinionated and structured: it fits when the system has more than 30 modules and many hands on it, like TalentUs.

Used in TalentUs

Ant Design

Enterprise-grade tables, filters and forms solved out of the box. For management dashboards it saves months.

Used in ResiHub Cliento

Tailwind CSS

When the design is our own and we don't want to fight a library's styles. Consistency without stylesheets that grow out of control.

Used in Billium Cliento

shadcn/ui + Radix

UI

Accessible components you copy into your repo and control. Without being tied to a third party's design decisions.

Used in Billium

TanStack Query

State

Caching, revalidation and loading states without writing them by hand on every screen. Less code and fewer subtle bugs.

Used in Billium

Zod + React Hook Form

Forms

Declarative, typed validation. The schema that validates the form is the same source that defines the type.

Used in Billium

dnd-kit

Kanban

Accessible drag and drop, keyboard-friendly too. It's what moves the Cliento pipeline.

Used in Cliento

Recharts · ApexCharts

Charts

Bar, donut, area and stacked charts for the property-manager, sales and invoicing dashboards.

Used in ResiHub Cliento TalentUs

ExcelJS · jsPDF

Export

Real export: multi-sheet Excel and PDF with tables and charts. Because the client will always ask "send it to me in Excel."

Used in ResiHub Cliento

Vite

Build

Near-instant startup and reload. Sounds like a detail, but multiplied by every change in a day it changes the team's rhythm.

Used in Cliento

04 Móvil

Two published apps, one codebase.

ResiHub Mobile and ResiHub Handy share backend and architecture, but they're independent projects. Everything in this section is in production, not in a tutorial.

React Native

iOS and Android from a single codebase, with truly native components. And it shares language and types with the backend.

Used in Mobile y Handy

Expo

It handles the most thankless part: permissions, camera, notifications, certificates and builds. Handy runs on the New Architecture.

Used in Mobile y Handy

EAS Build

Publishing

Cloud builds and store submission. Without a dedicated Mac or an afternoon fighting Apple certificates.

Used in Mobile y Handy

Expo Local Authentication

Biometrics

Face ID, Touch ID and fingerprint. The resident logs in without typing a password, which is the difference between using the app and uninstalling it.

Used in ResiHub Mobile

Expo Notifications

Push

Notifications that actually arrive: visitor at the gate, payment received, management announcement.

Used in Mobile y Handy

Expo Camera

QR

QR code scanning at the gate. Security validates the visit without calling anyone.

Used in Mobile y Handy

NativeWind

Tailwind inside React Native. One styling language between the web dashboard and the app.

Used in Mobile y Handy

Gluestack UI

UI

Accessible mobile components, consistent across platforms, without building every control from scratch.

Used in ResiHub Mobile

Custom offline client

Custom

In Handy we wrote our own fetch client: retries, timeout, multi-tenant headers and read cache. Field staff don't always have signal.

Used in ResiHub Handy

05 Datos

The one thing you can't redo.

Code gets rewritten; data doesn't. That's why the model and the migrations are taken seriously from day one: that ResiHub has evolved for years in production without losing a record or cutting off the service isn't luck, it's method.

PostgreSQL

Our default choice. Solid, free, and with details that really matter: partial unique indexes are what allow soft delete without blocking emails or invoice numbers.

Used in ResiHub Cliento Billium

SQL Server

Enterprise

When the client already has a license and a DBA who knows it. Fighting that wastes everyone's time.

Used in TalentUs

TypeORM

Versioned migrations and, above all, subscribers: they apply the tenant filter automatically. No one can forget to filter.

Used in ResiHub Cliento

Entity Framework Core

Migrations and per-tenant filtering. In TalentUs, identity and application data live separately.

Used in TalentUs

Managed database

AWS · Azure

Managed PostgreSQL in the cloud, with backups and high availability handled by the provider. No database servers to patch by hand.

Used in ResiHub Billium

Power BI

BI

When the client wants to explore their data on their own, instead of asking us for a new report each time.

Used in Service

06 Infraestructura

Make deploying routine, not an event.

If shipping is scary, you ship rarely; and if you ship rarely, each release piles up more risk. Infrastructure exists to break that cycle.

Docker

Containers

The environment is defined in a file and is identical on your machine and in production. No more "it works on my computer."

Used in ResiHub Cliento

GitHub Actions

CI/CD

Automated tests and deployment on every push. This very site is published this way.

Used in ResiHub Cliento

AWS · Azure

Cloud

We deploy on enterprise cloud, with managed services for the frontend and the backend. No servers to administer or midnight OS patches.

Used in ResiHub Cliento

CDN and delivery

AWS · Azure

Our own CDN for receipts and documents. The resident opens their receipt fast, from wherever they are.

Used in ResiHub

Swappable storage

Agnostic

ResiHub's file layer is agnostic: AWS S3, Azure Blob and local disk implement the same interface and are chosen with an environment variable. Moving a deployment from one cloud to another is changing that variable, not rewriting code.

Used in ResiHub

AWS S3

Implemented

A complete provider: IAM credentials, region, separate public and private buckets and presigned URLs — the file downloads straight from S3 with a temporary link, without passing through our server.

Used in ResiHub

Azure Blob Storage

Implemented

The alternative when the client is already on Microsoft. Same contract as S3 inside our code, so choosing one or the other doesn't touch business logic.

Used in ResiHub

Serilog + Seq

Logs

Structured logging: logs are queried like data, not read by eye. When something fails, it's found.

Used in Billium

Health checks

Monitoring

The system reports whether it's healthy, including its database. Finding out from the client isn't monitoring.

Used in Billium

Swagger / OpenAPI

Docs

The API contract documented and browsable. Whoever integrates doesn't have to guess or write to us.

Used in ResiHub Cliento Billium TalentUs

reCAPTCHA

v3 · Enterprise

Login protection against bots, without making the user identify traffic lights.

Used in ResiHub

Analytics

Product

Measure what's actually used and what isn't. Product decisions come from here, not from opinions.

Used in ResiHub

07 Seguridad

Controls on the server and in the application.

Security isn't a box you tick at the end: it's layers applied automatically on every request. These are the ones our systems run in production — from HTTP headers to encryption of credentials at rest.

Helmet

HTTP security headers on every response: CSP, HSTS, X-Frame-Options and X-Content-Type-Options. It closes the door on clickjacking, MIME sniffing and much of XSS.

Used in ResiHub

Rate limiting

Throttler

A request limit per origin, applied with a global guard. It's what stops someone from trying ten thousand passwords against the login while no one's watching.

Used in ResiHub

BCrypt

Hashing

Passwords are stored as a salted hash, never in plain text or reversibly encrypted. If the database leaked, there are no passwords to steal.

Used in ResiHub Cliento Billium

Strict input validation

Whitelist

Every request is validated against a schema and every undeclared field is discarded. No one can sneak a role: "admin" into a form body and escalate privileges.

Used in ResiHub Cliento

AES-256-GCM

Encryption

Sensitive credentials are stored encrypted at rest, with authenticated encryption: if someone tampers with the stored data, decryption fails instead of returning garbage.

Used in ResiHub

CORS

Origin

Only declared origins can talk to the API. A third-party site can't call it from your user's browser.

Used in ResiHub Cliento

Per-request guards

Authorization

Permission isn't checked at login but on every call. In ResiHub, a global guard verifies the property manager still has that condominium assigned, or returns 403.

Used in ResiHub Cliento

Session revocation

JWT

Deactivating a user or suspending an organization cuts the active session: the refresh tokens are revoked and the next request is rejected. No waiting for the token to expire.

Used in ResiHub Cliento

reCAPTCHA

v3 · Enterprise

Filters bots at login by score, without making the user identify traffic lights or stairs.

Used in ResiHub

Edge protection

WAF · CDN

Malicious traffic is filtered before it touches the server. DDoS mitigation and managed TLS without configuring certificates by hand.

Used in ResiHub

SHA-256 integrity

Voting

Every vote carries an integrity hash and duplicate control. An assembly's result can be audited, not just believed.

Used in ResiHub

Auditing and soft delete

Traceability

An audit log in the database and in files, and soft delete across the whole system: nothing truly disappears, and you can always reconstruct who did what.

Used in ResiHub Cliento TalentUs

08 Artificial Intelligence

VERA: an assistant that queries, not one that makes things up.

Almost everyone says they "have AI." The right question is another: where does it get the data? A loose model hallucinates figures. One with tools queries your database and answers with what's actually there.

Language models

LLM

The engine behind VERA, ResiHub's assistant. We choose the model for its reliability using tools and following instructions, and the integration stays isolated so we can swap models without touching the rest of the system.

Used in ResiHub

Tool use

3 tools

VERA has custom tools —query delinquency, summarize payments, draft communications— and reads bank transfer receipts by vision. Every answer comes from a real query.

Used in ResiHub

Domain assistants

Approach

No generic chatbot stuck in a corner. VERA lives inside the system, with the context and permissions of the user asking, and every action is audited.

Used in ResiHub

09 Criteria

How we decide what to use.

Choosing technology is easy when the criterion is "what's trendy" or "what I know." We use these four, in this order.

Who will maintain it?

It's the first question, not the last. If your team codes in C#, building you something in Node leaves you tied to us — and that's not a good deal for you. The right technology is the one your people can sustain.

Will it exist in five years?

We prefer boring tools with a large community over the novelty of the month. PostgreSQL, React and .NET aren't going anywhere. A framework with 400 GitHub stars and a single maintainer, maybe.

Does it solve the real problem?

CQRS in Billium makes sense because issuing and querying receipts are different worlds. Putting CQRS in a simple CRUD is complexity with no return. The pattern earns its place, it doesn't come for free.

Can you get out later?

Nothing critical should be locked to a vendor. ResiHub's storage is the example: AWS S3, Azure Blob and local disk implement the same interface, and choosing one or another is an environment variable. We wrote those providers before needing them, precisely to avoid getting trapped in one cloud.

Does your team already work with any of these?

Even better: we can build on what they already know and hand them something they can maintain without us. Tell us what you work with.