Skip to content

Repository files navigation

GitHub license GitHub Release GitHub Actions Workflow Status Coverage

Shared Finances

Easily manage your personal and family finances. Free and open source.

Important notes

Caution

We are in alpha version. So be aware of possible bugs.

Warning

This project was created with help of AI. I know this is a barrier for many people, so please be aware.

Features

  • ‼️ Open Source
  • ‼️ Privacy: we don't collect any data
  • 2FA authentication
  • Dark mode
  • Bank accounts
  • Credit cards
  • Individual financial transactions
  • Financial transactions of a group/family
  • Recurrence financial transaction
  • Financial transaction with installment purchase
  • Dashboard and charts
  • Multilanguage support (for now only english and brazilian portuguese)
  • Financial goals
  • Simulation of a new expense can show if you can afford it
  • Support of many currencies, including cryptocurrencies. (You can see the list here)
  • Import transactions from CSV/OFX
  • Export transactions AS CSV (⌛ Planned)
  • PDF report (⌛ Planned)
  • Email before due date (✖️ Not planned)

Self Hosted

You can self-host this project using docker compose. First pick your version at GitHub Packages.

All-in-one VS only project

First you need to choose if you just want the only Shared Finances or Shared Finances and their dependencies.

  • Choose only Shared Finances if you have experience with Docker and prefers to adjust things your way.
  • Choose Shared Finances and their dependencies if you want a simpler setup.

Common configurations

This configuration parameters are common between only Shared Finances and Shared Finances and their dependencies.

Parameter Type Required Default Sample Description
SF_APP_POSTGRES_CONNECTION_STRING string X postgresql://localhost:5432/shared_finances Postgres connection string
SF_APP_POSTGRES_USER string X shared_finances_user Postgres user
SF_APP_POSTGRES_PASSWORD string X shared_finances_pass Postgres password
SF_APP_REDIS_HOST string X localhost Redis host
SF_APP_REDIS_PASSWORD string redis_password Redis password
SF_APP_REDIS_PORT number X 6379 Redis port
SF_APP_NATS_HOST string X localhost Nats host
SF_APP_NATS_PORT number X 4222 Nats port
SF_APP_NATS_USER string X client_user Nats user
SF_APP_NATS_PASSWORD string X client_pass Nats password
SF_APP_FILE_STORAGE_PATH string X /var/lib/shared-finances/files Writable directory used to persist application files. It must be backed up and mounted as a persistent volume when running in a container.
SF_APP_PORT number 80 Shared Finances HTTP public port (not exists in backend-only image)
SF_APP_API_PORT number 8081 Shared FInances API port (internal in combined image; exposed in backend-only image; not exists in frontend-only image)
SF_APP_INVITATION_EXPIRATION_MINUTES number 15 Time, in minutes, before expiration of group invitation
SF_APP_REGISTRATION_ENABLED boolean true false Enables new user registrations. When disabled, registration is blocked even for users arriving through an invitation; existing-user login remains available.
SF_APP_LEGAL_DOCUMENTS_ENABLED boolean false true Presents the shipped terms of use and privacy policy together and records their versions at registration. The shipped text describes the maintainer's public instance; an operator enabling this for another instance must review and replace the content with documents for that operation.
SF_APP_ENABLE_LIMITS boolean false true Enables the plan model. When false, limits and quotas are not enforced or presented, limits pages and plan badges are hidden, and dormant-account deletion is disabled.
SF_APP_DEFAULT_ROLE user, pro, or administrator pro user Plan role assigned only to accounts created after this value is set. Existing accounts keep their stored role.
SF_APP_JWT_PUBLIC_KEY string X Public key for JWT authentication.
Click here to learn how to generate this
SF_APP_JWT_PRIVATE_KEY string X Private key for JWT authentication.
Click here to learn how to generate this
SF_APP_JWT_KID number 1 Rotation number of JWT key
SF_APP_JWT_ISSUER string shared_finances The JWT issuer name
SF_APP_JWT_ACCESS_TOKEN_TTL_MINUTES number 15 Time, in minutes, before user login token expires
SF_APP_JWT_REFRESH_TOKEN_TTL_MINUTES number 43200 Time, in minutes, before user login refresh token expires
SF_APP_WRONG_PASSWORD_BLOCK number 10 How many times user can get your password wrong before block for SF_APP_WRONG_PASSWORD_TTL_MINUTES minutes.
SF_APP_WRONG_PASSWORD_TTL_MINUTES number 120 Time, in minutes, that user will cannot try login again after SF_APP_WRONG_PASSWORD_BLOCK wrong attempts.
SF_APP_SECURE_COOKIE boolean false Defines whether refresh cookie will only be sent by the browser on HTTPS connections.
If you have https please change this to true
SF_APP_MFA_TOTP_CRYPTO_PASSWORD string changeme Password used to safe store MFA
SF_APP_MFA_TOTP_CRYPTO_SALT_HEX string 8e69438719bb1ebbd72c650e1b3262eb Password-like used to safe store MFA
You can generate with openssl rand -hex 16
SF_APP_SERVICE_SECRET string X service-secret Password used to authenticate as server
SF_APP_PUBLIC_WEB_BASE_URL string X http://localhost:4200 Public URL of shared finances. Used on email links.
SF_APP_TURNSTILE_SECRET_KEY string 1x0000000000000000000000000000000AA Cloudflare captcha.
If you want to use this you'll need to build frontend and change environment turnstileSiteKey
SF_APP_TURNSTILE_VERIFY_URL string https://challenges.cloudflare.com/turnstile/v0/siteverify
SF_APP_EMAIL_CONFIRMATION_ENABLED boolean false Whether it is needed confirm account via email before login.
SF_APP_PASSWORD_RECOVERY_ENABLED boolean false Wwhether it is possible to recover the password via email.
SF_APP_TX_MAIL_PROVIDER_PRIORITY list of string brevo,smtp Email servers, separated by commas, should be used to send emails. The further to the left, the higher the priority. If empty, emails will never be sent.
SF_APP_BREVO_DAILY_QUOTA number 300 Brevo daily quota for sending email. When quota is over is tried the next email server (if exists).
SF_APP_BREVO_API_KEY string Brevo api key
SF_APP_BREVO_FROM_ADDRESS string sample@domain.com Email on 'from' used in Brevo
SF_APP_BREVO_FROM_NAME string Shared Finances Name on 'from' used in Brevo
SF_APP_SMTP_HOST string localhost SMTP host
SF_APP_SMTP_PORT number 1025 SMTP port
SF_APP_SMTP_USERNAME string SMTP username
SF_APP_SMTP_PASSWORD string SMTP password
SF_APP_SMTP_AUTH boolean false If SMTP needs authentication
SF_APP_SMTP_STARTTLS boolean false SMTP STARTTLS
SF_APP_TX_MAIL_SMTP_FROM string noreply@localhost Email on 'from' used in SMTP
SF_APP_TX_MAIL_SMTP_FROM_NAME string Shared Finances Name on 'from' used in SMTP
SF_APP_LEGAL_TERMS_VERSION date (yyyy-mm-dd) 2026-08-10 Date of terms of use
SF_APP_LEGAL_PRIVACY_VERSION date (yyyy-mm-dd) 2026-08-10 Date of terms of privacy
SF_APP_EXCHANGE_RATES_PROVIDER_URL string https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@ Provider of exchange rates.
Note: for now only fawazahmed0/exchange-api is supported.
SF_APP_REFRESH_EXCHANGE_RATES_CRON string (cron) 0 0 0/12 * * * Cron to get new exchange rates
SF_APP_MATERIALIZE_GOAL_CRON string (cron) 0 0 0 * * * Cron to generate scheduled financial goals.
SF_APP_GENERATE_ENTRY_CRON string (cron) 0 0 0 * * * Cron to generate scheduled financial transactions.
SF_APP_EXPIRE_INVITES_CRON string (cron) 0 0/30 * * * * Cron to delete expired group invites.
SF_APP_UNCONFIRMED_ACCOUNT_CLEANUP_CRON string (cron) 0 0 0 * * * Cron to delete not confirmed accounts.
SF_APP_SIMULATION_RECONCILE_CRON_ENABLED boolean false
SF_APP_SIMULATION_RECONCILE_CRON string (cron) 0 */2 * * * *
SF_APP_SIMULATION_PURGE_CRON string (cron) 0 30 3 * * * Cron to delete old financial simulations.
SF_APP_IMPORT_WORKER_ENABLED boolean true Enables the durable JetStream consumer for asynchronous CSV imports.
SF_APP_IMPORT_RECONCILE_CRON_ENABLED boolean true Enables reconciliation of queued imports and expired worker leases.
SF_APP_IMPORT_RECONCILE_CRON string (cron) 0 */1 * * * * Cron for asynchronous CSV import reconciliation.
SF_APP_INACTIVE_ACCOUNT_DELETION_ENABLED boolean false Setting it to true enables warning e-mails and permanently deletes inactive accounts and their financial records after the retention period configured for their plan. Owned groups are deleted with the account.
SF_APP_INACTIVE_ACCOUNT_DELETION_CRON string (cron) 0 0 2 * * * Cron used to delete inactive accounts. Only if SF_APP_INACTIVE_ACCOUNT_DELETION_ENABLED is true.

SF_APP_REGISTRATION_ENABLED, SF_APP_LEGAL_DOCUMENTS_ENABLED, and SF_APP_ENABLE_LIMITS accept true or false, and SF_APP_DEFAULT_ROLE accepts user, pro, or administrator. Invalid values prevent the backend from starting. These settings are read at startup, so restart every application replica after changing them. SF_APP_DEFAULT_ROLE applies only to accounts created after it is set; changing it never reassigns existing accounts. The maximum parsed rows in one import comes from the user's plan and is unbounded when the plan model is disabled. Limits are off unless SF_APP_ENABLE_LIMITS=true; enabling it activates stored plan limits, quota enforcement, plan/usage presentation, and permits dormant-account deletion when that feature's own switch is also enabled.

The legal documents are disabled unless SF_APP_LEGAL_DOCUMENTS_ENABLED=true. The bundled English and Brazilian Portuguese text is written for the public instance operated by this project's maintainer. A self-hosting operator who wants to present legal documents must replace that content with terms and a privacy policy that identify and describe their own operation before enabling the switch.

See Async CSV import operations for rollout, monitoring, and rollback procedures.

Only Shared Finances Setup

Requirements

  • Postgres 18+
  • Redis 8+
  • Nats
  • A writable persistent directory for application files

Instalation

  1. create docker-compose.yml file.

    name: shared-finances
    
    services:
      shared-finances:
        image: ghcr.io/ynixt/shared-finances:main-20260423-200705-f54e237
        restart: unless-stopped
        stop_grace_period: 45s
        env_file:
          - .env
        environment:
          SF_APP_PORT: ${SF_APP_PORT:-80}
          SF_APP_FILE_STORAGE_PATH: /var/lib/shared-finances/files
        ports:
          - "${SF_APP_PORT:-80}:${SF_APP_PORT:-80}"
        volumes:
          - file_data:/var/lib/shared-finances/files
        depends_on:
          db:
            condition: service_healthy
          redis:
            condition: service_healthy
          nats:
            condition: service_healthy
        healthcheck:
          test: ["CMD-SHELL", "curl -fsS http://localhost:$${SF_APP_PORT:-80}/api/open/actuator/health >/dev/null || exit 1"]
          interval: 20s
          timeout: 5s
          retries: 6
          start_period: 20s
    
    volumes:
      file_data:
  2. Create .env file. (remember to change user/password/et.)

    So here's a sample:

     ## Postgres
     SF_APP_POSTGRES_CONNECTION_STRING=postgresql://localhost:5432/shared_finances
     SF_APP_POSTGRES_USER=shared_finances_user
     SF_APP_POSTGRES_PASSWORD=shared_finances_pass
    
     ## Redis
     SF_APP_REDIS_HOST=localhost
     SF_APP_REDIS_PASSWORD=redis_password
     SF_APP_REDIS_PORT=6379
    
     ## NATS
     SF_APP_NATS_HOST=localhost
     SF_APP_NATS_PORT=4222
     SF_APP_NATS_USER=client_user
     SF_APP_NATS_PASSWORD=client_pass
    
     ## File storage
     SF_APP_FILE_STORAGE_PATH=/var/lib/shared-finances/files
    
     ## APP
     SF_APP_INVITATION_EXPIRATION_MINUTES=15
     SF_APP_JWT_PUBLIC_KEY=nice_token_here
     SF_APP_JWT_PRIVATE_KEY=nice_private_token_here
     SF_APP_JWT_KID=k1
     SF_APP_JWT_ISSUER=self_hosted_shared_finances
     SF_APP_JWT_ACCESS_TOKEN_TTL_MINUTES=15
     SF_APP_JWT_REFRESH_TOKEN_TTL_MINUTES=43200
     SF_APP_WRONG_PASSWORD_TTL_MINUTES=120
     SF_APP_MFA_TOTP_CRYPTO_PASSWORD=changeme
     SF_APP_MFA_TOTP_CRYPTO_SALT_HEX=8e69438719bb1ebbd72c650e1b3262eb
     SF_APP_SERVICE_SECRET=service-secret
  3. Run docker compose up -d

  4. Open in your browser http://localhost

File storage operations

All application files are stored below SF_APP_FILE_STORAGE_PATH. The application validates this directory at startup and refuses to start if it cannot create, read, and write files there.

  • Back up the file-storage volume together with Postgres. Losing either one can leave file references or content incomplete.
  • When running more than one application replica, every replica must mount the same shared filesystem at SF_APP_FILE_STORAGE_PATH. Independent local disks are not supported.
  • The development backend uses ./data/files from dev.env; this directory is created automatically and should remain outside source control.

Shared Finances and their dependencies

Coming soon

Screenshots

Desktop

Mobile

Acknowledgments

License

GNU Affero General Public License v3.0 (AGPL-3.0). See LICENSE.

About

A project written in spring + angular to control personal and group finances

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages