Skip to main content

Frontend - Tech Stack

Repository: finmars-platform/finmars-vue-portal and finmars-platform/finmars-portal and finmars-platform/finmars-workflow-portal

Overview

This document describes the technology stack used in the Vue Portal frontend.

Language

  • JavaScript / TypeScript

Framework

  • Vue 3 (main frontend framework)
  • Angular.js (for finmars-platform/finmars-portal)

Build Tool

  • Vite

State Management

  • Pinia

Router

  • Vue Router

UI / Styling

  • CSS / SCSS
  • TailwindCSS or UI component library (Naive UI / Element Plus / Vuetify)

API Layer

  • HTTP Client: likely Axios
  • Backend: Django REST Framework (from core), communication over REST/JSON

Authentication

  • Keycloak (mandatory integration). Client library: keycloak-js

Environment & Config

  • .env files for environment variables (e.g., VITE_*) — exact names to be confirmed

Testing

  • E2E Testing: Cypress / Playwright (separate repository)

Linting & Formatting

  • ESLint, Prettier — rules and configs

CI/CD

  • GitHub Actions (build and deploy). Build process based on Dockerfile

Containerization

  • Docker (Dockerfile)
  • Docker Compose for local development — to be confirmed

Observability

  • Logging and monitoring for the frontend — Sentry

License

  • EUPL-1.2 (repository license)



finmars-vue-portal package.json


{
	"private": true,
	"scripts": {
		"build": "nuxt build ",
		"build:web-component": "vite build",
		"dev": "nuxt --rootDir=./v/ dev -p=3000",
		"dev-local": "NUXT_APP_BUILD_ASSETS_DIR=/realm00000/v/_nuxt/ API_HOST=http://0.0.0.0:8000 AUTH_HOST=http://0.0.0.0:8083/authorizer nuxt --rootDir=./v/ dev --host=0.0.0.0",
		"start": "PORT=8080 node .output/server/index.mjs",
		"generate": "nuxt generate",
		"preview": "nuxt preview",
		"test": "vitest",
		"coverage": "vitest run --coverage"
	},
	"author": "Finmars SCSA",
	"license": "EUPL-1.2",
	"devDependencies": {
		"@nuxt/test-utils": "^3.12.1",
		"@nuxtjs/tailwindcss": "^6.12.1",
		"@types/sanitize-html": "^2.13.0",
		"@vitest/coverage-v8": "3.2.4",
		"@vue/test-utils": "^2.4.5",
		"consola": "^3.2.0",
		"eslint": "^8.24.0",
		"eslint-plugin-vue": "^9.6.0",
		"happy-dom": "^17.0.0",
		"nuxt": "^3.11.0",
		"postcss-mixins": "^10.0.1",
		"prettier": "3.3.3",
		"sass": "1.85.1",
		"unplugin-auto-import": "^0.16.6",
		"unplugin-vue-components": "^0.25.1",
		"vite-plugin-commonjs": "^0.10.1",
		"vitest": "3.2.4"
	},
	"dependencies": {
		"@chenfengyuan/vue-qrcode": "^2.0.0",
		"@finmars/ui": "1.0.87",
		"@formbricks/js": "1.1.2",
		"@kyvg/vue3-notification": "^2.4.1",
		"@pinia/nuxt": "^0.5.1",
		"@vue/web-component-wrapper": "^1.3.0",
		"ace-builds": "^1.36.2",
		"chart.js": "^3.9.1",
		"click-outside-vue3": "^4.0.1",
		"dayjs": "^1.11.7",
		"esbuild": "^0.25.5",
		"eslint-config-prettier": "^9.1.0",
		"eslint-plugin-prettier": "^5.2.1",
		"floating-vue": "^5.2.2",
		"grid-layout-plus": "^1.0.6",
		"jquery": "^3.7.1",
		"jsondiffpatch": "^0.6.0",
		"jstree": "^3.3.17",
		"keycloak-js": "^21.0.1",
		"lodash": "^4.17.21",
		"pdfjs-dist": "^4.0.269",
		"pinia": "^2.0.24",
		"qrcode": "^1.5.1",
		"sanitize-html": "^2.13.1",
		"swiper": "^10.0.4",
		"vue": "^3.4.23",
		"vue-matomo": "^4.2.0",
		"vue3-ace-editor": "^2.2.2",
		"vuedraggable": "^4.1.0"
	}
}