diff --git a/.gitignore b/.gitignore
index 351e74c381b04026dc2dbbb0fc157424d2accd33..ebc7c7a15cd76f5f19b2613f752ff29055b2ccda 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,4 @@ node_modules
 !/example.env
 /.svelte-kit
 /build/
-/package
+/src/lib/openfisca
diff --git a/.prettierignore b/.prettierignore
index 7dde8a0aed1f0aaeeae5e90d104331528e2d9950..5421174f88eb85ad3050ba62f557dbdcdffc0e08 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,4 +1,5 @@
 .svelte-kit/**
 build/**
 node_modules/**
+src/lib/openfisca/**
 static/**
diff --git a/README.md b/README.md
index 68efa4bb97c7ed8b42ccb325f98671720aff33f3..a999f7feee58b77ec19c09840fb60e7ac2e7fffb 100644
--- a/README.md
+++ b/README.md
@@ -21,11 +21,13 @@ Pour fonctionner, ce simulateur socio-fiscal utilise un export des paramètres e
 git clone https://git.leximpact.dev/openfisca/openfisca-france-json
 ```
 
-Une fois ces différentes opérations effectuées, exécuter les commandes ci-dessous pour vous déplacer dans le répertoire du projet et installer les librairies nécessaires :
+Une fois ces différentes opérations effectuées, exécuter les commandes ci-dessous pour vous déplacer dans le répertoire du projet, le lier aux paramètres et variables d'OpenFisca, puis installer les librairies nécessaires :
 
 ```shell
 git clone https://git.leximpact.dev/leximpact/leximpact-socio-fiscal-ui
-cd leximpact-socio-fiscal-ui/
+cd leximpact-socio-fiscal-ui/src/lib/
+ln -s ../../../openfisca-france-json openfisca
+cd ../../
 npm install
 ```
 
diff --git a/example.env b/example.env
index ed965d086cfeb7b32e9b505e7a9e3cb2947da210..c4b88768f24549d4412ab39e0c386fda6c6f1ee8 100644
--- a/example.env
+++ b/example.env
@@ -14,9 +14,6 @@ BASE_URL="http://localhost:3000"
 # Key for children in a family
 CHILDREN_KEY="enfants"
 
-# Path to file containing decompositions in JSON format
-DECOMPOSITION_PATH="../openfisca-france-json/decompositions/decompositions_customized.json"
-
 # Key for family entity
 FAMILY_KEY="famille"
 
@@ -28,9 +25,6 @@ GITHUB_PERSONAL_ACCESS_TOKEN=null
 # that should not be shown when editing test cases
 HIDDEN_ENTITIES=menages
 
-# Directory containing JSON export of OpenFisca country package
-JSON_DIR="../openfisca-france-json"
-
 # Matomo analytics configuration
 # MATOMO_SITE_ID=123
 # MATOMO_URL="https://MATOMO_SERVER/"
@@ -61,6 +55,3 @@ PROXY=false
 SIMULATIONS_DIR="../simulations"
 
 TITLE="Simulateur socio-fiscal"
-
-# Path to file containing description of waterfalls in JSON format
-WATERFALLS_PATH="../openfisca-france-json/custom/waterfalls.json"
diff --git a/src/hooks.ts b/src/hooks.ts
index c17459a8fa3297146c34575fd763698ecfee8aed..54357d651f1f37abd1ca8cb8edf769ce7b221541 100644
--- a/src/hooks.ts
+++ b/src/hooks.ts
@@ -2,16 +2,7 @@ import type { GetSession, Handle } from "@sveltejs/kit"
 import fetch, { Response, Request, Headers } from "node-fetch"
 
 import config from "$lib/server/config"
-import {
-  decompositionCoreByName,
-  decompositionsOptionsVariablesName,
-  waterfalls,
-} from "$lib/server/decompositions"
-import { entityByKey, personEntityKey } from "$lib/server/entities"
-import { metadata } from "$lib/server/metadata"
 import { oauth2Authenticator } from "$lib/server/oauth2"
-import { leafParametersName } from "$lib/server/parameters"
-import { testCases } from "$lib/server/situations"
 import type { Session } from "$lib/sessions"
 
 // Globally declare fetch, because it is not (yet?) available  in @sveltejs/adapter-node,
@@ -51,15 +42,10 @@ export const getSession: GetSession<{}, Session> = async (request) => {
     authenticationEnabled: oauth2Authenticator !== undefined,
     baseUrl: config.baseUrl,
     childrenKey: config.childrenKey,
-    decompositionCoreByName,
-    decompositionsOptionsVariablesName,
-    entityByKey,
     familyEntityKey: config.familyEntityKey,
     hasGithubPersonalAccessToken: githubPersonalAccessToken !== undefined,
     hiddenEntitiesKeyPlural: config.hiddenEntitiesKeyPlural,
-    leafParametersName,
     matomo: config.matomo,
-    metadata,
     openfiscaRepository: {
       branch: openfiscaRepository.branch,
       group: openfiscaRepository.group,
@@ -67,12 +53,9 @@ export const getSession: GetSession<{}, Session> = async (request) => {
       rawUrlTemplate: openfiscaRepository.rawUrlTemplate,
       urlTemplate: openfiscaRepository.urlTemplate,
     },
-    personEntityKey,
     portalUrl: config.portalUrl,
-    testCases,
     title: config.title,
     user,
-    waterfalls,
   }
 }
 
diff --git a/src/lib/auditors/config.ts b/src/lib/auditors/config.ts
index 122f80aee7c17d12534225fc97f5e1129b7e2ab0..b2fc30b85e14c9ad675e4f996b614fb51d4ca0bc 100644
--- a/src/lib/auditors/config.ts
+++ b/src/lib/auditors/config.ts
@@ -67,12 +67,10 @@ export function auditConfig(
   }
   for (const key of [
     "childrenKey",
-    "decompositionsPath",
     "familyEntityKey",
-    "jsonDir",
+    "openfiscaDir",
     "simulationsDir",
     "title",
-    "waterfallsPath",
   ]) {
     audit.attribute(
       data,
diff --git a/src/lib/components/parameters/NodeEdit.svelte b/src/lib/components/parameters/NodeEdit.svelte
index ebd57a69ba8df227b5582aacd10a84d4059b25eb..de3a10ae2035ff5277bbd5d5670db874ee01977f 100644
--- a/src/lib/components/parameters/NodeEdit.svelte
+++ b/src/lib/components/parameters/NodeEdit.svelte
@@ -3,9 +3,9 @@
   import type { NodeParameter, Reference } from "@openfisca/ast"
   import { Unit } from "@openfisca/ast"
 
-  import { session } from "$app/stores"
   import ReferencesEdit from "$lib/components/parameters/ReferencesEdit.svelte"
   import { errorAsKeyValueDictionary, iterArrayWithErrors } from "$lib/errors"
+  import { metadata } from "$lib/metadata"
   import { labelFromUnit } from "$lib/parameters"
 
   let globalErrors: { [key: string]: unknown }
@@ -21,8 +21,6 @@
   let errors = globalErrors
   let instantReferencesArray = buildInstantReferencesArray(parameter)
 
-  $: metadata = $session.metadata
-
   function addInstantReferences() {
     instantReferencesArray = [
       {
diff --git a/src/lib/components/parameters/ParameterPane.svelte b/src/lib/components/parameters/ParameterPane.svelte
index 9feb72dc3dec10b6e33d6d5529df56da4e66bf58..9bf2a8be2a36ed9dbd8021e65c093648a0c015ed 100644
--- a/src/lib/components/parameters/ParameterPane.svelte
+++ b/src/lib/components/parameters/ParameterPane.svelte
@@ -1,31 +1,14 @@
 <script lang="ts">
-  import type { Parameter } from "@openfisca/ast"
-  import { improveParameterWithAncestors } from "@openfisca/ast"
-
-  import { browser } from "$app/env"
   import ParameterView from "$lib/components/parameters/ParameterView.svelte"
+  import { getParameter } from "$lib/parameters"
 
   export let name: string
   // export let pane: string
 
-  let parameter: Parameter | undefined = undefined
-
-  $: browser && retrieveParameter(name)
+  $: parameter = getParameter(name)
 
-  async function retrieveParameter(name: string): Promise<void> {
-    const url = `/parameters/${name}.json`
-    const res = await fetch(url)
-    if (res.ok) {
-      const parameterWithAncestors = await res.json()
-      parameter = improveParameterWithAncestors(parameterWithAncestors)
-    } else {
-      console.error(
-        `Error ${
-          res.status
-        } while retrieving parameter "${name}" at ${url}\n\n${await res.text()}`,
-      )
-      parameter = undefined
-    }
+  $: if (parameter === undefined) {
+    console.error(`Parameter "${name}" not found`)
   }
 </script>
 
diff --git a/src/lib/components/parameters/ParameterView.svelte b/src/lib/components/parameters/ParameterView.svelte
index 12c0230f82a694c44da39488ba5cbd80a6269f18..3a830cd3d2546a33fe1f03406af07e1778191c6b 100644
--- a/src/lib/components/parameters/ParameterView.svelte
+++ b/src/lib/components/parameters/ParameterView.svelte
@@ -15,8 +15,8 @@
   } from "@openfisca/ast"
   import { getContext } from "svelte"
 
-  import { session } from "$app/stores"
   import ScaleView from "$lib/components/parameters/ScaleView.svelte"
+  import { metadata } from "$lib/metadata"
   import {
     buildInstantReferencesAndValueArray,
     labelFromScaleType,
@@ -32,8 +32,6 @@
     url: string,
   ) => SelfTargetAProps
 
-  $: metadata = $session.metadata
-
   $: parameterRepositoryUrl = newParameterRepositoryUrl(metadata, parameter)
 
   function asAmountScaleParameter(
diff --git a/src/lib/components/parameters/ScaleEdit.svelte b/src/lib/components/parameters/ScaleEdit.svelte
index a77f3582fcfb47732175f4bc9236ed357570232e..907f9cafe57ce045715e8aee05c45d899d5c01ed 100644
--- a/src/lib/components/parameters/ScaleEdit.svelte
+++ b/src/lib/components/parameters/ScaleEdit.svelte
@@ -20,11 +20,11 @@
   } from "@openfisca/ast"
   import { deepCopy } from "fast-deep-copy"
 
-  import { session } from "$app/stores"
   import ReferencesEdit from "$lib/components/parameters/ReferencesEdit.svelte"
   import ScaleAtInstantEdit from "$lib/components/parameters/ScaleAtInstantEdit.svelte"
   import { errorAsKeyValueDictionary, iterArrayWithErrors } from "$lib/errors"
   import { iterToLimit } from "$lib/iterators"
+  import { metadata } from "$lib/metadata"
   import {
     buildInstantReferencesAndScaleArray,
     labelFromScaleType,
@@ -43,8 +43,6 @@
   let showAll = false
   const useBase = false
 
-  $: metadata = $session.metadata
-
   $: isAmountScale = isAmountScaleParameter(parameter)
 
   function addInstantReferencesAndScale() {
diff --git a/src/lib/components/parameters/ValueAtInstantEdit.svelte b/src/lib/components/parameters/ValueAtInstantEdit.svelte
index 23b4640baac69c9047067f46993a32b81401867a..3a8f2173db0a6365e7cefb7ab5bce822cda0b2ba 100644
--- a/src/lib/components/parameters/ValueAtInstantEdit.svelte
+++ b/src/lib/components/parameters/ValueAtInstantEdit.svelte
@@ -16,8 +16,8 @@
   import { Unit, ValueType } from "@openfisca/ast"
   import { createEventDispatcher } from "svelte"
 
-  import { session } from "$app/stores"
   import { auditEditedAttribute } from "$lib/errors"
+  import { metadata } from "$lib/metadata"
   import { labelFromUnit } from "$lib/parameters"
 
   let globalErrors: { [key: string]: unknown }
@@ -30,8 +30,6 @@
   let errors = globalErrors
   const oldValueAtInstant = valueAtInstant
 
-  $: metadata = $session.metadata
-
   function asMaybeNumberValue(
     value:
       | MaybeNumberValue
diff --git a/src/lib/components/parameters/ValueEdit.svelte b/src/lib/components/parameters/ValueEdit.svelte
index f5b96ab79e526c227218cd210281b5208e1597c8..6de28559f8c5febdadae94b8c06dba6aea391e39 100644
--- a/src/lib/components/parameters/ValueEdit.svelte
+++ b/src/lib/components/parameters/ValueEdit.svelte
@@ -7,11 +7,11 @@
   } from "@openfisca/ast"
   import { Unit, ValueType } from "@openfisca/ast"
 
-  import { session } from "$app/stores"
   import ReferencesEdit from "$lib/components/parameters/ReferencesEdit.svelte"
   import ValueAtInstantEdit from "$lib/components/parameters/ValueAtInstantEdit.svelte"
   import { errorAsKeyValueDictionary, iterArrayWithErrors } from "$lib/errors"
   import { iterToLimit } from "$lib/iterators"
+  import { metadata } from "$lib/metadata"
   import {
     buildInstantReferencesAndValueArray,
     labelFromValueType,
@@ -29,8 +29,6 @@
     buildInstantReferencesAndValueArray(parameter)
   let showAll = false
 
-  $: metadata = $session.metadata
-
   function addInstantReferencesAndValue() {
     instantReferencesAndValueArray = [
       {
diff --git a/src/lib/components/scholar_waterfalls/ScholarWaterfall.svelte b/src/lib/components/scholar_waterfalls/ScholarWaterfall.svelte
index a73252f264a22cbe17f5a320dff16d952f967edd..6a72681900cf63357adea963e089896cb907ffb8 100644
--- a/src/lib/components/scholar_waterfalls/ScholarWaterfall.svelte
+++ b/src/lib/components/scholar_waterfalls/ScholarWaterfall.svelte
@@ -10,6 +10,7 @@
     VisibleDecomposition,
   } from "$lib/decompositions"
   import { buildVisibleDecompositions } from "$lib/decompositions"
+  import { entityByKey } from "$lib/entities"
   import type { Situation } from "$lib/situations"
 
   export let decompositionByName: DecompositionByName
@@ -44,7 +45,7 @@
 
   $: visibleDecompositions = buildVisibleDecompositions(
     decompositionByName,
-    $session.entityByKey,
+    entityByKey,
     evaluationByName,
     situation,
     variableSummaryByName,
diff --git a/src/lib/components/test_cases/TestCaseEdit.svelte b/src/lib/components/test_cases/TestCaseEdit.svelte
index 1ec5cabba4e78d680f90e660be58c691ffbc4077..fd02fddac8c53cc9130b539c64cca8eb8168074c 100644
--- a/src/lib/components/test_cases/TestCaseEdit.svelte
+++ b/src/lib/components/test_cases/TestCaseEdit.svelte
@@ -4,7 +4,6 @@
     GroupEntity,
     PersonEntity,
     Role,
-    Variable,
   } from "@openfisca/ast"
   import { getRolePersonsIdKey, isAdultRole, isChildRole } from "@openfisca/ast"
   import { createEventDispatcher } from "svelte"
@@ -14,10 +13,11 @@
   import PictoEnfant from "$lib/components/pictos/PictoEnfant.svelte"
   import RolePersonsEdit from "$lib/components/test_cases/RolePersonsEdit.svelte"
   import VariableInput from "$lib/components/variables/VariableInput.svelte"
-  import type { DecompositionCoreByName } from "$lib/decompositions"
+  import { decompositionCoreByName } from "$lib/decompositions"
+  import { entityByKey, personEntityKey } from "$lib/entities"
   import type { Axis, PopulationWithoutId, Situation } from "$lib/situations"
   import { iterSituationVariablesName } from "$lib/situations"
-  import { retrieveVariableSummaryByName } from "$lib/variables"
+  import { variableSummaryByName } from "$lib/variables"
 
   export let inputInstantsByVariableName: {
     [name: string]: Set<string>
@@ -28,7 +28,6 @@
   let currentInputInstantsByVariableName = inputInstantsByVariableName
   let currentSituation = situation
   const dispatch = createEventDispatcher()
-  const entityByKey = $session.entityByKey as EntityByKey
   const [, firstGroupEntity] = Object.entries(entityByKey).filter(
     ([, entity]) => !entity.is_person,
   )[0] as [string, GroupEntity]
@@ -40,15 +39,12 @@
   ].map((_, index) => `Enfant ${index + 1}`)
   const hiddenEntitiesKeyPlural = ($session.hiddenEntitiesKeyPlural ??
     []) as string[]
-  const personEntityKey = $session.personEntityKey as string
   const personEntity = entityByKey[personEntityKey] as PersonEntity
   let variablesName = new Set(
-    Object.entries($session.decompositionCoreByName as DecompositionCoreByName)
+    Object.entries(decompositionCoreByName)
       .filter(([, decomposition]) => !decomposition.virtual)
       .map(([name]) => name),
   )
-  let variableSummaryByName: { [name: string]: Variable } | undefined =
-    undefined
 
   $: persons = Object.entries(
     (situation[personEntity.key_plural] ?? {}) as {
@@ -67,12 +63,6 @@
 
   $: updateVariablesName(situation)
 
-  $: retrieveVariableSummaryByName($session.baseUrl, [...variablesName]).then(
-    (result) => {
-      variableSummaryByName = result
-    },
-  )
-
   $: updateInputInstantsByVariableName(inputInstantsByVariableName)
 
   $: updateSituation(situation)
@@ -548,22 +538,20 @@
   {/each}
 </section>
 
-{#if variableSummaryByName !== undefined}
-  <section class="border-t border-b-0 border-r-0 border-l-0 mt-5">
-    <h1 class="font-bold mt-3 text-xl">Caractéristiques du cas type&nbsp;:</h1>
-    <ul>
-      {#each Object.values(variableSummaryByName) as variable}
-        {#if (inputInstantsByVariableName[variable.name] ?? new Set()).has(yearString)}
-          <li>
-            <VariableInput
-              bind:inputInstantsByVariableName
-              bind:situation
-              {variable}
-              {year}
-            />
-          </li>
-        {/if}
-      {/each}
-    </ul>
-  </section>
-{/if}
+<section class="border-t border-b-0 border-r-0 border-l-0 mt-5">
+  <h1 class="font-bold mt-3 text-xl">Caractéristiques du cas type&nbsp;:</h1>
+  <ul>
+    {#each [...variablesName] as variableName}
+      {#if (inputInstantsByVariableName[variableName] ?? new Set()).has(yearString)}
+        <li>
+          <VariableInput
+            bind:inputInstantsByVariableName
+            bind:situation
+            variable={variableSummaryByName[variableName]}
+            {year}
+          />
+        </li>
+      {/if}
+    {/each}
+  </ul>
+</section>
diff --git a/src/lib/components/test_cases/TestCaseView.svelte b/src/lib/components/test_cases/TestCaseView.svelte
index fa08bcaa6897b0ad0aaff5f3fb556393d3b5f345..35b8113bdde283450dd87cafd755059814f785b4 100644
--- a/src/lib/components/test_cases/TestCaseView.svelte
+++ b/src/lib/components/test_cases/TestCaseView.svelte
@@ -1,10 +1,5 @@
 <script lang="ts">
-  import type {
-    DecompositionReference,
-    EntityByKey,
-    Variable,
-    Waterfall,
-  } from "@openfisca/ast"
+  import type { DecompositionReference, Waterfall } from "@openfisca/ast"
   import { createEventDispatcher, getContext } from "svelte"
   import type { Writable } from "svelte/store"
 
@@ -17,18 +12,18 @@
   import type {
     CalculationName,
     DecompositionByName,
-    DecompositionCoreByName,
     EvaluationByName,
     EvaluationByNameArrayByCalculationName,
   } from "$lib/decompositions"
+  import { waterfalls } from "$lib/decompositions"
+  import { entityByKey, personEntityKey } from "$lib/entities"
   import type { Reform } from "$lib/reforms"
   import type { AxisDescription, Situation } from "$lib/situations"
   import {
     getSituationVariableValue,
-    iterSituationVariablesName,
     setSituationVariableValue,
   } from "$lib/situations"
-  import { retrieveVariableSummaryByName } from "$lib/variables"
+  import { variableSummaryByName } from "$lib/variables"
 
   export let calculationName: CalculationName
   export let decompositionByName: DecompositionByName
@@ -46,7 +41,6 @@
   const childrenKey = $session.childrenKey
   const dispatch = createEventDispatcher()
   const enfantVariablesName = ["age"]
-  const entityByKey = $session.entityByKey as EntityByKey
   const euroAmountFormatter = new Intl.NumberFormat("fr-FR", {
     currency: "EUR",
     maximumFractionDigits: 0,
@@ -54,7 +48,7 @@
     style: "currency",
   })
   const familyEntity = entityByKey[$session.familyEntityKey]
-  const personEntity = entityByKey[$session.personEntityKey]
+  const personEntity = entityByKey[personEntityKey]
   const reform = getContext("reform") as Writable<Reform>
   const variableDefinitionByName = {
     age: {
@@ -70,18 +64,7 @@
       min: 0,
     },
   }
-  let variablesName = new Set([
-    ...$session.decompositionsOptionsVariablesName,
-    ...Object.entries(
-      $session.decompositionCoreByName as DecompositionCoreByName,
-    )
-      .filter(([, decomposition]) => !decomposition.virtual)
-      .map(([name]) => name),
-  ])
-  let variableSummaryByName: { [name: string]: Variable } | undefined =
-    undefined
   const waterfall = getContext("waterfall") as Writable<Waterfall>
-  const waterfalls = $session.waterfalls
 
   $: familySituation = situation[familyEntity.key_plural]
 
@@ -98,14 +81,6 @@
 
   $: adultsCount = Object.keys(personSituation).length - childrenCount
 
-  $: updateVariablesName(situation)
-
-  $: retrieveVariableSummaryByName($session.baseUrl, [...variablesName]).then(
-    (result) => {
-      variableSummaryByName = result
-    },
-  )
-
   // $: updateSituation(year, adultes, enfants)
 
   function calculateTotal(
@@ -251,17 +226,6 @@
     dispatch("changeVectorIndex", vectorIndex)
     dispatch("changeAxis", axisDescription)
   }
-
-  function updateVariablesName(situation: Situation) {
-    const newVariablesName = [
-      ...iterSituationVariablesName(entityByKey, situation),
-    ]
-    if (
-      newVariablesName.some((variableName) => !variablesName.has(variableName))
-    ) {
-      variablesName = new Set([...variablesName, ...newVariablesName])
-    }
-  }
 </script>
 
 <div class="place-self-start shadow-md w-full rounded-t-sm bg-white mb-5 ">
diff --git a/src/lib/components/test_cases/TestCasesPane.svelte b/src/lib/components/test_cases/TestCasesPane.svelte
index 2d4f9f1a19e978bc67b18e45fb13af756ca65438..001d7a9fb146ce7d1d9b6a53344bab5ef1f31b25 100644
--- a/src/lib/components/test_cases/TestCasesPane.svelte
+++ b/src/lib/components/test_cases/TestCasesPane.svelte
@@ -1,14 +1,13 @@
 <script lang="ts">
-  import type { EntityByKey } from "@openfisca/ast"
   import { createEventDispatcher, getContext } from "svelte"
   import type { Writable } from "svelte/store"
 
-  import { session } from "$app/stores"
   import type {
     CalculationName,
     DecompositionByName,
     EvaluationByNameArrayByCalculationName,
   } from "$lib/decompositions"
+  import { entityByKey } from "$lib/entities"
   import type { Axis, AxisDescription, Situation } from "$lib/situations"
   import { indexOfSituationPopulationId } from "$lib/situations"
 
@@ -24,7 +23,6 @@
     "decompositionByName",
   ) as Writable<DecompositionByName>
   const dispatch = createEventDispatcher()
-  const entityByKey = $session.entityByKey as EntityByKey
   const evaluationByNameArrayByCalculationName = getContext(
     "evaluationByNameArrayByCalculationName",
   ) as Writable<EvaluationByNameArrayByCalculationName>
diff --git a/src/lib/components/variables/FormulaView.svelte b/src/lib/components/variables/FormulaView.svelte
index 74e591080836fdd3ce7acc3b70fa6c4995803ef9..1613d4e57791a1e6f52c6c01ad91ab9819e22647 100644
--- a/src/lib/components/variables/FormulaView.svelte
+++ b/src/lib/components/variables/FormulaView.svelte
@@ -1,5 +1,5 @@
 <script lang="ts">
-  import type { Formula, Variable } from "@openfisca/ast"
+  import type { Formula } from "@openfisca/ast"
   import {
     extractFromFormulaAst,
     newFormulaRepositoryUrl,
@@ -8,10 +8,12 @@
   import type { Writable } from "svelte/store"
 
   import { browser } from "$app/env"
-  import { session } from "$app/stores"
   import VariableInput from "$lib/components/variables/VariableInput.svelte"
+  import { entityByKey } from "$lib/entities"
+  import { metadata } from "$lib/metadata"
+  import { leafParametersName } from "$lib/parameters"
   import type { Situation } from "$lib/situations"
-  import { retrieveVariableSummaryByName } from "$lib/variables"
+  import { variableSummaryByName } from "$lib/variables"
   import type { WebSocketByName, WebSocketOpenByName } from "$lib/websockets"
 
   export let formula: Formula
@@ -21,8 +23,6 @@
   export let situation: Situation
   export let year: number
 
-  let variableSummaryByName: { [name: string]: Variable } | undefined =
-    undefined
   const webSocketByName = getContext("webSocketByName") as Writable<
     WebSocketByName | undefined
   >
@@ -32,29 +32,24 @@
 
   $: extraction = extractFromFormulaAst(
     formula.ast,
-    $session.entityByKey,
-    $session.leafParametersName,
+    entityByKey,
+    leafParametersName,
   )
 
-  $: metadata = $session.metadata
-
   $: if (browser && $webSocketOpenByName.law) {
     calculateVariables(extraction.openFiscaVariablesName)
   }
 
   async function calculateVariables(variablesName: Set<string>) {
-    variableSummaryByName = await retrieveVariableSummaryByName(
-      $session.baseUrl,
-      [...variablesName],
-    )
-
-    $webSocketByName.law.send(
-      JSON.stringify({
-        calculate: true,
-        title: "law",
-        variables: Object.keys(variableSummaryByName),
-      }),
-    )
+    if (variablesName.size > 0) {
+      $webSocketByName.law.send(
+        JSON.stringify({
+          calculate: true,
+          title: "law",
+          variables: [...variablesName],
+        }),
+      )
+    }
   }
 </script>
 
@@ -68,19 +63,19 @@
   <pre
     class="bg-gray-100 p-5 text-sm whitespace-pre-wrap">{formula.source_code}</pre>
   <!-- {#if formula.parameters !== undefined}
-              <section>
-                <h1>Paramètres référencés</h1>
-                <ul class="list-disc list-inside">
-                  {#each formula.parameters as parameterName}
-                    <li>
-                      <a class="link" href="/parameters/{parameterName}"
-                        >{parameterName}</a
-                      >
-                    </li>
-                  {/each}
-                </ul>
-              </section>
-            {/if} -->
+    <section>
+      <h1>Paramètres référencés</h1>
+      <ul class="list-disc list-inside">
+        {#each formula.parameters as parameterName}
+          <li>
+            <a class="link" href="/parameters/{parameterName}"
+              >{parameterName}</a
+            >
+          </li>
+        {/each}
+      </ul>
+    </section>
+  {/if} -->
 </div>
 <p class="my-4">
   <a
@@ -124,19 +119,19 @@
     </section>
   {/if}
   <!-- {#if formula.variables !== undefined}
-              <section>
-                <h1>Variables référencées</h1>
-                <ul class="list-disc list-inside">
-                  {#each formula.variables as variableName}
-                    <li>
-                      <a class="text-gray-900 hover:text-le-bleu underline" href="/variables/{variableName}"
-                        >{variableName}</a
-                      >
-                    </li>
-                  {/each}
-                </ul>
-              </section>
-            {/if} -->
+    <section>
+      <h1>Variables référencées</h1>
+      <ul class="list-disc list-inside">
+        {#each formula.variables as variableName}
+          <li>
+            <a class="text-gray-900 hover:text-le-bleu underline" href="/variables/{variableName}"
+              >{variableName}</a
+            >
+          </li>
+        {/each}
+      </ul>
+    </section>
+  {/if} -->
   {#if variableSummaryByName !== undefined && Object.keys(variableSummaryByName).length > 0}
     <section class="mb-2">
       <h3 class="mb-1  ">Variables&nbsp;:</h3>
diff --git a/src/lib/components/variables/VariableInput.svelte b/src/lib/components/variables/VariableInput.svelte
index 09fb71f1804fd17f8bfd1fc92f023bf53e937651..4ffaaea4bd5ec305e4b85ec4a0625bc07ceec568 100644
--- a/src/lib/components/variables/VariableInput.svelte
+++ b/src/lib/components/variables/VariableInput.svelte
@@ -4,9 +4,9 @@
   import { getContext } from "svelte"
   import type { Writable } from "svelte/store"
 
-  import { session } from "$app/stores"
   import type { CalculationName } from "$lib/decompositions"
   import { calculationNames } from "$lib/decompositions"
+  import { entityByKey } from "$lib/entities"
   import type { Situation } from "$lib/situations"
   import {
     getSituationVariableValue,
@@ -25,7 +25,7 @@
   ) as Writable<Set<CalculationName>>
   let valueError = null
 
-  $: entity = $session.entityByKey[variable.entity]
+  $: entity = entityByKey[variable.entity]
 
   $: entitySituation = situation[entity.key_plural]
 
@@ -77,7 +77,7 @@
         break
     }
     const updatedSituation = setSituationVariableValue(
-      $session.entityByKey,
+      entityByKey,
       situation,
       variable,
       populationId,
@@ -138,7 +138,7 @@
                 on:blur={(event) => changeValue(event, populationId)}
                 on:change={(event) => changeValue(event, populationId)}
                 value={getSituationVariableValue(
-                  $session.entityByKey,
+                  entityByKey,
                   situation,
                   variable,
                   populationId,
@@ -154,7 +154,7 @@
                 <input
                   checked={asBoolean(
                     getSituationVariableValue(
-                      $session.entityByKey,
+                      entityByKey,
                       situation,
                       variable,
                       populationId,
@@ -165,7 +165,7 @@
                   on:change={(event) => changeValue(event, populationId)}
                   type="checkbox"
                 />
-                {#if asBoolean(getSituationVariableValue($session.entityByKey, situation, variable, populationId, year))}Oui{:else}Non{/if}
+                {#if asBoolean(getSituationVariableValue(entityByKey, situation, variable, populationId, year))}Oui{:else}Non{/if}
               </label>
             {:else if variable.value_type === "date"}
               <input
@@ -174,7 +174,7 @@
                 type="date"
                 value={asString(
                   getSituationVariableValue(
-                    $session.entityByKey,
+                    entityByKey,
                     situation,
                     variable,
                     populationId,
@@ -189,7 +189,7 @@
                 type="number"
                 value={asNumber(
                   getSituationVariableValue(
-                    $session.entityByKey,
+                    entityByKey,
                     situation,
                     variable,
                     populationId,
@@ -204,7 +204,7 @@
                 type="text"
                 value={asString(
                   getSituationVariableValue(
-                    $session.entityByKey,
+                    entityByKey,
                     situation,
                     variable,
                     populationId,
diff --git a/src/lib/components/variables/VariableReferredInputsPane.svelte b/src/lib/components/variables/VariableReferredInputsPane.svelte
index f1692455daaebbc4226decd9a6886b0ac03fbcec..a41aea3656f137e97d47c1c9853a2ba74342e75b 100644
--- a/src/lib/components/variables/VariableReferredInputsPane.svelte
+++ b/src/lib/components/variables/VariableReferredInputsPane.svelte
@@ -3,9 +3,17 @@
   import { createEventDispatcher, getContext } from "svelte"
   import type { Writable } from "svelte/store"
 
-  import { browser } from "$app/env"
-  import VariableReferredInputs from "./VariableReferredInputs.svelte"
+  import {
+    decompositionCoreByName,
+    walkDecompositionsCoreName,
+  } from "$lib/decompositions"
   import type { Situation } from "$lib/situations"
+  import {
+    iterVariableInputVariables,
+    variableSummaryByName,
+  } from "$lib/variables"
+
+  import VariableReferredInputs from "./VariableReferredInputs.svelte"
 
   export let date: string
   export let inputInstantsByVariableName: {
@@ -18,51 +26,31 @@
   let currentInputInstantsByVariableName = inputInstantsByVariableName
   let currentSituation = situation
   const dispatch = createEventDispatcher()
-  let inputs: Variable[] | undefined = undefined
-  let variable: Variable | undefined = undefined
   const waterfall = getContext("waterfall") as Writable<Waterfall>
 
-  $: browser && retrieveVariable(name)
+  $: variable = variableSummaryByName[name]
+
+  $: if (variable === undefined) {
+    console.error(`Variable "${name}" not found`)
+  }
 
-  $: browser && retrieveVariableReferredInputs(name, date)
+  $: inputs = getVariableReferredInputs(name, date)
 
   $: updateInputInstantsByVariableName(inputInstantsByVariableName)
 
   $: updateSituation(situation)
 
-  async function retrieveVariable(name: string): Promise<void> {
-    const url = `/variables/${name}.json`
-    const res = await fetch(url)
-    if (res.ok) {
-      variable = await res.json()
-    } else {
-      console.error(
-        `Error ${
-          res.status
-        } while retrieving referred input variables of variable "${name}" at ${url}\n\n${await res.text()}`,
-      )
-      variable = undefined
-    }
-  }
-
-  async function retrieveVariableReferredInputs(
-    name: string,
-    date: string,
-  ): Promise<void> {
-    const url = `/variables/${name}/inputs/${date}.json?filter_decomposition=true&waterfall=${encodeURIComponent(
-      $waterfall.name,
-    )}`
-    const res = await fetch(url)
-    if (res.ok) {
-      inputs = await res.json()
-    } else {
-      console.error(
-        `Error ${
-          res.status
-        } while retrieving referred input variables of variable "${name}" at ${url}\n\n${await res.text()}`,
-      )
-      inputs = undefined
-    }
+  function getVariableReferredInputs(name: string, date: string): Variable[] {
+    const ignoreVariablesName = new Set(
+      walkDecompositionsCoreName(
+        decompositionCoreByName,
+        $waterfall.name,
+        $waterfall.root,
+        false,
+      ),
+    )
+    ignoreVariablesName.delete(name)
+    return [...iterVariableInputVariables(variable, date, ignoreVariablesName)]
   }
 
   function updateInputInstantsByVariableName(inputInstantsByVariableName: {
@@ -84,7 +72,7 @@
   }
 </script>
 
-{#if inputs !== undefined && variable !== undefined}
+{#if variable !== undefined}
   <VariableReferredInputs
     {date}
     bind:inputInstantsByVariableName
diff --git a/src/lib/components/variables/VariableReferredParameters.svelte b/src/lib/components/variables/VariableReferredParameters.svelte
index 12ff6799cd107ae7b3369fb454757937e3974a79..366fb879dbc6021a38723548c381a4ca4d84179e 100644
--- a/src/lib/components/variables/VariableReferredParameters.svelte
+++ b/src/lib/components/variables/VariableReferredParameters.svelte
@@ -1,14 +1,11 @@
 <script lang="ts">
   import type { Parameter, Variable } from "@openfisca/ast"
   import {
-    getVariableFormula,
     getVariableLatestFormulaDate,
     mergeParameters,
     ParameterClass,
   } from "@openfisca/ast"
 
-  import { session } from "$app/stores"
-
   import VariableReferredNodeParameter from "./VariableReferredNodeParameter.svelte"
   import VariableReferredScaleParameter from "./VariableReferredScaleParameter.svelte"
   import VariableReferredValueParameter from "./VariableReferredValueParameter.svelte"
@@ -19,14 +16,8 @@
 
   const dateFormatter = new Intl.DateTimeFormat("fr-FR", { dateStyle: "full" })
 
-  $: directParametersName = getVariableFormula(variable, date)?.parameters ?? []
-
   $: latestFormulaDate = getVariableLatestFormulaDate(variable)
 
-  $: metadata = $session.metadata
-
-  $: openAllParameters = directParametersName.length === 0
-
   $: rootParameterById = mergeParameters(parameters)
 </script>
 
diff --git a/src/lib/components/variables/VariableReferredParametersPane.svelte b/src/lib/components/variables/VariableReferredParametersPane.svelte
index 9357a73035884f32eb1e55fc5f7a3873687439e9..f43d48b956480dc356aaaf0370d10abf11e87171 100644
--- a/src/lib/components/variables/VariableReferredParametersPane.svelte
+++ b/src/lib/components/variables/VariableReferredParametersPane.svelte
@@ -1,56 +1,21 @@
 <script lang="ts">
-  import type { Parameter, Variable } from "@openfisca/ast"
-  import { improveParameterWithAncestors } from "@openfisca/ast"
+  import { iterVariableParameters, variableSummaryByName } from "$lib/variables"
 
-  import { browser } from "$app/env"
-  import VariableReferredParameters from "$lib/components/variables/VariableReferredParameters.svelte"
+  import VariableReferredParameters from "./VariableReferredParameters.svelte"
 
   export let date: string
   export let name: string
   // export let pane: string
 
-  let variable: Variable | undefined = undefined
-  let parameters: Parameter[] | undefined = undefined
+  $: variable = variableSummaryByName[name]
 
-  $: browser && retrieveVariable(name)
-
-  $: browser && retrieveVariableReferredParameters(name, date)
-
-  async function retrieveVariable(name: string): Promise<void> {
-    const url = `/variables/${name}.json`
-    const res = await fetch(url)
-    if (res.ok) {
-      variable = await res.json()
-    } else {
-      console.error(
-        `Error ${
-          res.status
-        } while retrieving referred input variables of variable "${name}" at ${url}\n\n${await res.text()}`,
-      )
-      variable = undefined
-    }
+  $: if (variable === undefined) {
+    console.error(`Variable "${name}" not found`)
   }
 
-  async function retrieveVariableReferredParameters(
-    name: string,
-    date: string,
-  ): Promise<void> {
-    const url = `/variables/${name}/parameters/${date}.json`
-    const res = await fetch(url)
-    if (res.ok) {
-      const parametersWithAncestors = await res.json()
-      parameters = parametersWithAncestors.map(improveParameterWithAncestors)
-    } else {
-      console.error(
-        `Error ${
-          res.status
-        } while retrieving referred parameters of variable "${name}" at ${url}\n\n${await res.text()}`,
-      )
-      parameters = undefined
-    }
-  }
+  $: parameters = [...iterVariableParameters(variable, date)]
 </script>
 
-{#if parameters !== undefined && variable !== undefined}
+{#if variable !== undefined}
   <VariableReferredParameters {date} {parameters} {variable} />
 {/if}
diff --git a/src/lib/components/variables/VariableView.svelte b/src/lib/components/variables/VariableView.svelte
index 97a3746a91ef28ff528a6a8c3d39d3a64733f53a..053307359609698a2fa5765934cbb710d434400b 100644
--- a/src/lib/components/variables/VariableView.svelte
+++ b/src/lib/components/variables/VariableView.svelte
@@ -5,10 +5,11 @@
   import { getContext } from "svelte"
   import type { Writable } from "svelte/store"
 
-  import { session } from "$app/stores"
   import FormulaView from "$lib/components/variables/FormulaView.svelte"
   import type { CalculationName } from "$lib/decompositions"
   import { calculationNames } from "$lib/decompositions"
+  import { entityByKey } from "$lib/entities"
+  import { metadata } from "$lib/metadata"
   import type { Situation } from "$lib/situations"
   import {
     getSituationVariableValue,
@@ -35,12 +36,10 @@
   ) as Writable<Set<CalculationName>>
   let valueError = null
 
-  $: entity = $session.entityByKey[variable.entity]
+  $: entity = entityByKey[variable.entity]
 
   $: entitySituation = situation[entity.key_plural]
 
-  $: metadata = $session.metadata
-
   function asBoolean(value: boolean | number | string): boolean {
     return value as boolean
   }
@@ -89,7 +88,7 @@
         break
     }
     const updatedSituation = setSituationVariableValue(
-      $session.entityByKey,
+      entityByKey,
       situation,
       variable,
       populationId,
@@ -268,7 +267,7 @@
                 on:blur={(event) => changeValue(event, populationId)}
                 on:change={(event) => changeValue(event, populationId)}
                 value={getSituationVariableValue(
-                  $session.entityByKey,
+                  entityByKey,
                   situation,
                   variable,
                   populationId,
@@ -284,7 +283,7 @@
                 <input
                   checked={asBoolean(
                     getSituationVariableValue(
-                      $session.entityByKey,
+                      entityByKey,
                       situation,
                       variable,
                       populationId,
@@ -295,7 +294,7 @@
                   on:change={(event) => changeValue(event, populationId)}
                   type="checkbox"
                 />
-                {#if asBoolean(getSituationVariableValue($session.entityByKey, situation, variable, populationId, year))}Oui{:else}Non{/if}
+                {#if asBoolean(getSituationVariableValue(entityByKey, situation, variable, populationId, year))}Oui{:else}Non{/if}
               </label>
             {:else if variable.value_type === "date"}
               <input
@@ -304,7 +303,7 @@
                 type="date"
                 value={asString(
                   getSituationVariableValue(
-                    $session.entityByKey,
+                    entityByKey,
                     situation,
                     variable,
                     populationId,
@@ -319,7 +318,7 @@
                 type="number"
                 value={asNumber(
                   getSituationVariableValue(
-                    $session.entityByKey,
+                    entityByKey,
                     situation,
                     variable,
                     populationId,
@@ -334,7 +333,7 @@
                 type="text"
                 value={asString(
                   getSituationVariableValue(
-                    $session.entityByKey,
+                    entityByKey,
                     situation,
                     variable,
                     populationId,
diff --git a/src/lib/decompositions.ts b/src/lib/decompositions.ts
index 4c4313cac0c6ec9b0ac765dab559a8afd00555eb..f8c6640ced10de731a779fec338b23b429777569 100644
--- a/src/lib/decompositions.ts
+++ b/src/lib/decompositions.ts
@@ -12,6 +12,8 @@ import type {
   WaterfallOptions,
 } from "@openfisca/ast"
 
+import decompositionCoreByNameUnknown from "$lib/openfisca/decompositions.json"
+import waterfallsUnknown from "$lib/openfisca/waterfalls.json"
 import type { Situation } from "$lib/situations"
 
 export type CalculationName = "amendment" | "bill" | "law"
@@ -57,6 +59,29 @@ export interface VisibleDecomposition {
 
 export const calculationNames: CalculationName[] = ["law", "bill", "amendment"]
 
+export const decompositionCoreByName: DecompositionCoreByName =
+  decompositionCoreByNameUnknown
+
+export const waterfalls: Waterfall[] = waterfallsUnknown
+
+export const decompositionsOptionsVariablesName = new Set<string>()
+for (const decompositionCore of Object.values(decompositionCoreByName)) {
+  if (decompositionCore.options === undefined) {
+    continue
+  }
+  for (const options of decompositionCore.options) {
+    if (options.waterfall !== undefined) {
+      continue
+    }
+    for (const variableName of Object.keys(options)) {
+      if (["else", "then"].includes(variableName)) {
+        continue
+      }
+      decompositionsOptionsVariablesName.add(variableName)
+    }
+  }
+}
+
 export function buildDecompositionByNameFromCore(
   decompositionCoreByName: DecompositionCoreByName,
 ): DecompositionByName | undefined {
diff --git a/src/lib/entities.ts b/src/lib/entities.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d8080195ce15f033aa84ca8a24c2276d431fc45a
--- /dev/null
+++ b/src/lib/entities.ts
@@ -0,0 +1,9 @@
+import type { EntityByKey } from "@openfisca/ast"
+
+import entityByKeyUnknown from "$lib/openfisca/entities.json"
+
+export const entityByKey = entityByKeyUnknown as EntityByKey
+
+export const personEntityKey = Object.entries(entityByKey)
+  .filter(([, entity]) => entity.is_person)
+  .map(([key]) => key)[0]
diff --git a/src/lib/metadata.ts b/src/lib/metadata.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bc7a6f4af34c26b62593b63ab150561ca8f38e34
--- /dev/null
+++ b/src/lib/metadata.ts
@@ -0,0 +1,5 @@
+import type { Metadata } from "@openfisca/ast"
+
+import metadataUnknown from "$lib/openfisca/metadata.json"
+
+export const metadata: Metadata = metadataUnknown
diff --git a/src/lib/parameters.ts b/src/lib/parameters.ts
index 75441af62bc3a1563b3fc49a6eb4a607e9ff5892..0447ea76a81dc0204a4a795cfd885099d9392ba7 100644
--- a/src/lib/parameters.ts
+++ b/src/lib/parameters.ts
@@ -1,7 +1,7 @@
-import { scaleByInstantFromBrackets } from "@openfisca/ast"
-
 import type {
   Metadata,
+  NodeParameter,
+  Parameter,
   Reference,
   ScaleAtInstant,
   ScaleParameter,
@@ -10,13 +10,18 @@ import type {
 } from "@openfisca/ast"
 import {
   AmountUnit,
+  improveParameter,
   ParameterClass,
   RateUnit,
+  scaleByInstantFromBrackets,
   ScaleType,
   Unit,
   ValueType,
 } from "@openfisca/ast"
 
+import rootParameterUnknown from "$lib/openfisca/editable_processed_parameters.json"
+import leafParametersNameUnknown from "$lib/openfisca/processed_parameters_names.json"
+
 export interface InstantReferencesAndScale {
   instant: string
   references: Reference[]
@@ -29,6 +34,11 @@ export interface InstantReferencesAndValue {
   valueAtInstant?: ValueAtInstant
 }
 
+export const leafParametersName = new Set(leafParametersNameUnknown)
+
+improveParameter(null, rootParameterUnknown as NodeParameter)
+export const rootParameter = rootParameterUnknown as NodeParameter
+
 export function buildInstantReferencesAndScaleArray(
   parameter: ScaleParameter,
 ): InstantReferencesAndScale[] {
@@ -86,6 +96,22 @@ export function buildInstantReferencesAndValueArray(
     .map(([, instantReferencesAndValue]) => instantReferencesAndValue)
 }
 
+export function getParameter(name: string): Parameter | undefined {
+  let parameter = rootParameter as Parameter
+  for (const id of name.split(".")) {
+    const children =
+      parameter.class === ParameterClass.Node ? parameter.children : undefined
+    if (children === undefined) {
+      return undefined
+    }
+    parameter = children[id]
+    if (parameter === undefined) {
+      return undefined
+    }
+  }
+  return parameter
+}
+
 export function labelFromParameterClass(
   parameterClass: ParameterClass | string,
 ): string {
diff --git a/src/lib/server/config.ts b/src/lib/server/config.ts
index 5261d12110dc240b1b1a3857dda479dba50ac024..8ae023cc65d7bed03766df681e84dfdd56bbb29f 100644
--- a/src/lib/server/config.ts
+++ b/src/lib/server/config.ts
@@ -8,11 +8,9 @@ export interface Config {
   apiWebSocketBaseUrls: string[]
   baseUrl: string
   childrenKey: string
-  decompositionsPath: string
   familyEntityKey: string
   githubPersonalAccessToken?: string
   hiddenEntitiesKeyPlural?: string[]
-  jsonDir: string
   matomo?: {
     prependDomain?: boolean
     siteId: number
@@ -27,6 +25,7 @@ export interface Config {
     jwtSecret: string
     profileUrl: string
   }
+  openfiscaDir: string
   openfiscaRepository: {
     branch: string
     group: string
@@ -38,7 +37,6 @@ export interface Config {
   proxy: boolean
   simulationsDir: string
   title: string
-  waterfallsPath: string
 }
 
 const [validConfig, error] = validateConfig({
@@ -46,11 +44,9 @@ const [validConfig, error] = validateConfig({
   apiBaseUrls: process.env["API_BASE_URLS"],
   baseUrl: process.env["BASE_URL"],
   childrenKey: process.env["CHILDREN_KEY"],
-  decompositionsPath: process.env["DECOMPOSITION_PATH"],
   familyEntityKey: process.env["FAMILY_KEY"],
   githubPersonalAccessToken: process.env["GITHUB_PERSONAL_ACCESS_TOKEN"],
   hiddenEntitiesKeyPlural: process.env["HIDDEN_ENTITIES"],
-  jsonDir: process.env["JSON_DIR"],
   matomo:
     process.env["MATOMO_SITE_ID"] && process.env["MATOMO_URL"]
       ? {
@@ -70,6 +66,7 @@ const [validConfig, error] = validateConfig({
         profileUrl: process.env["OAUTH2_PROFILE_URL"],
       }
     : null,
+  openfiscaDir: "src/lib/openfisca",
   openfiscaRepository: {
     branch: process.env["OPENFISCA_BRANCH"],
     group: process.env["OPENFISCA_GROUP"],
@@ -80,7 +77,6 @@ const [validConfig, error] = validateConfig({
   portalUrl: process.env["PORTAL_URL"],
   proxy: process.env["PROXY"],
   simulationsDir: process.env["SIMULATIONS_DIR"],
-  waterfallsPath: process.env["WATERFALLS_PATH"],
   title: process.env["TITLE"],
 })
 if (error !== null) {
diff --git a/src/lib/server/decompositions.ts b/src/lib/server/decompositions.ts
deleted file mode 100644
index 92776a19f84387f9095bd0427217c7aa11d72a5a..0000000000000000000000000000000000000000
--- a/src/lib/server/decompositions.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import {
-  auditChain,
-  auditCleanArray,
-  auditRequire,
-  strictAudit,
-} from "@auditors/core"
-import type { Waterfall } from "@openfisca/ast"
-import { auditDecompositionByName, auditWaterfall } from "@openfisca/ast"
-import fs from "fs-extra"
-
-import type { DecompositionCoreByName } from "$lib/decompositions"
-import config from "$lib/server/config"
-
-const { decompositionsPath, waterfallsPath } = config
-
-const [decompositionByName, decompositionByNameError] = auditChain(
-  auditDecompositionByName,
-  auditRequire,
-)(strictAudit, fs.readJsonSync(decompositionsPath)) as [
-  DecompositionCoreByName,
-  unknown,
-]
-if (decompositionByNameError !== null) {
-  console.error(decompositionsPath)
-  console.error(JSON.stringify(decompositionByName, null, 2))
-  console.error(JSON.stringify(decompositionByNameError, null, 2))
-  process.exit(1)
-}
-export const decompositionCoreByName = decompositionByName
-
-export const decompositionsOptionsVariablesName = new Set<string>()
-for (const decompositionCore of Object.values(decompositionCoreByName)) {
-  if (decompositionCore.options === undefined) {
-    continue
-  }
-  for (const options of decompositionCore.options) {
-    if (options.waterfall !== undefined) {
-      continue
-    }
-    for (const variableName of Object.keys(options)) {
-      if (["else", "then"].includes(variableName)) {
-        continue
-      }
-      decompositionsOptionsVariablesName.add(variableName)
-    }
-  }
-}
-
-const [validWaterfalls, waterfallsError] = auditChain(
-  auditCleanArray(auditWaterfall),
-  auditRequire,
-)(strictAudit, fs.readJsonSync(waterfallsPath)) as [Waterfall[], unknown]
-if (waterfallsError !== null) {
-  console.error(waterfallsPath)
-  console.error(JSON.stringify(validWaterfalls, null, 2))
-  console.error(JSON.stringify(waterfallsError, null, 2))
-  process.exit(1)
-}
-export const waterfalls = validWaterfalls
diff --git a/src/lib/server/entities.ts b/src/lib/server/entities.ts
deleted file mode 100644
index 3d2d7245a4484ec3d00349c0d49d6daadba182d0..0000000000000000000000000000000000000000
--- a/src/lib/server/entities.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import type { EntityByKey } from "@openfisca/ast"
-import fs from "fs-extra"
-import path from "path"
-
-import config from "$lib/server/config"
-
-const { jsonDir } = config
-
-let entitiesFilePath = path.join(jsonDir, "custom", "entities.json")
-if (!fs.pathExistsSync(entitiesFilePath)) {
-  entitiesFilePath = path.join(jsonDir, "entities.json")
-}
-export const entityByKey = fs.readJsonSync(entitiesFilePath) as EntityByKey
-
-export const personEntityKey = Object.entries(entityByKey)
-  .filter(([, entity]) => entity.is_person)
-  .map(([key]) => key)[0]
diff --git a/src/lib/server/metadata.ts b/src/lib/server/metadata.ts
deleted file mode 100644
index 36023018062b34fca98a73afacb6b69d4a473ede..0000000000000000000000000000000000000000
--- a/src/lib/server/metadata.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import type { Metadata } from "@openfisca/ast"
-import fs from "fs-extra"
-import path from "path"
-
-import config from "$lib/server/config"
-
-const { jsonDir } = config
-
-export const metadata = fs.readJsonSync(
-  path.join(jsonDir, "metadata.json"),
-) as Metadata
diff --git a/src/lib/server/parameters.ts b/src/lib/server/parameters.ts
deleted file mode 100644
index ef1e887346007e0d3b986f6efa8b294e5dd5fc58..0000000000000000000000000000000000000000
--- a/src/lib/server/parameters.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import type { NodeParameter, Parameter } from "@openfisca/ast"
-import { ParameterClass } from "@openfisca/ast"
-import fs from "fs-extra"
-import path from "path"
-
-import config from "$lib/server/config"
-
-const { jsonDir } = config
-
-export const leafParametersName = new Set(
-  fs.readJsonSync(
-    path.join(jsonDir, "processed_parameters_names.json"),
-  ) as string[],
-)
-
-export const parameters = fs.readJsonSync(
-  path.join(jsonDir, "editable_processed_parameters.json"),
-) as NodeParameter
-
-export function getParameterWithAncestors(
-  name: string,
-): [Parameter | undefined, NodeParameter[]] {
-  const ancestors = []
-  let parameter = parameters as Parameter
-  for (const id of name.split(".")) {
-    if (parameter.name) {
-      // Note: Skip root parameter.
-      ancestors.push(parameter)
-    }
-    const children =
-      parameter.class === ParameterClass.Node ? parameter.children : undefined
-    if (children === undefined) {
-      return [undefined, ancestors]
-    }
-    parameter = children[id]
-    if (parameter === undefined) {
-      return [undefined, ancestors]
-    }
-  }
-  return [parameter, ancestors]
-}
diff --git a/src/lib/server/situations.ts b/src/lib/server/situations.ts
deleted file mode 100644
index 8c8800608f9a0154886800a360b4596a167b8950..0000000000000000000000000000000000000000
--- a/src/lib/server/situations.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import type { Situation } from "$lib/situations"
-import fs from "fs-extra"
-import path from "path"
-
-import config from "$lib/server/config"
-
-const { jsonDir } = config
-
-export const testCases = fs.readJsonSync(
-  path.join(jsonDir, "test_cases.json"),
-) as Situation[]
diff --git a/src/lib/server/variables.ts b/src/lib/server/variables.ts
deleted file mode 100644
index 1c6e10683756bdb0ce672ef4fcab33fef9c5d076..0000000000000000000000000000000000000000
--- a/src/lib/server/variables.ts
+++ /dev/null
@@ -1,120 +0,0 @@
-import type {
-  NodeParameter,
-  Parameter,
-  Variable,
-  VariableByName,
-} from "@openfisca/ast"
-import fs from "fs-extra"
-import path from "path"
-
-import config from "$lib/server/config"
-import { getParameterWithAncestors } from "$lib/server/parameters"
-
-const { jsonDir } = config
-
-export const variableSummaryByName = fs.readJsonSync(
-  path.join(jsonDir, "variables_summaries.json"),
-) as VariableByName
-
-export function* iterVariableInputVariables(
-  variable: Variable,
-  date: string,
-  encounteredVariablesName: Set<string> = new Set(),
-): Generator<Variable, void> {
-  const name = variable.name
-  if (encounteredVariablesName.has(name)) {
-    return
-  }
-  encounteredVariablesName.add(name)
-
-  const formulas = variable.formulas
-  if (formulas === undefined) {
-    // Variable is an input variable.
-    yield variable
-    return
-  }
-  const dates = Object.keys(formulas).reverse()
-  let formula = undefined
-  for (const bestDate of dates) {
-    if (bestDate <= date) {
-      formula = formulas[bestDate]
-      break
-    }
-  }
-  if (formula == null) {
-    // No candidate date less than or equal to date found.
-    return
-  }
-  const referredVariablesName = formula.variables
-  if (referredVariablesName === undefined) {
-    return
-  }
-  for (const referredVariableName of referredVariablesName) {
-    const referredVariable = variableSummaryByName[referredVariableName]
-    yield* iterVariableInputVariables(
-      referredVariable,
-      date,
-      encounteredVariablesName,
-    )
-  }
-}
-
-export function* iterVariableParametersWithAncestors(
-  variable: Variable,
-  date: string,
-  encounteredParametersName: Set<string> = new Set(),
-  encounteredVariablesName: Set<string> = new Set(),
-): Generator<[Parameter, NodeParameter[]], void> {
-  const name = variable.name
-  if (encounteredVariablesName.has(name)) {
-    return
-  }
-  encounteredVariablesName.add(name)
-
-  const formulas = variable.formulas
-  if (formulas === undefined) {
-    return
-  }
-  const dates = Object.keys(formulas).reverse()
-  let formula = undefined
-  for (const bestDate of dates) {
-    if (bestDate <= date) {
-      formula = formulas[bestDate]
-      break
-    }
-  }
-  if (formula == null) {
-    // No candidate date less than or equal to date found.
-    return
-  }
-
-  const referredVariablesName = formula.variables
-  if (referredVariablesName !== undefined) {
-    for (const referredVariableName of referredVariablesName) {
-      const referredVariable = variableSummaryByName[referredVariableName]
-      yield* iterVariableParametersWithAncestors(
-        referredVariable,
-        date,
-        encounteredParametersName,
-        encounteredVariablesName,
-      )
-    }
-  }
-
-  const referredParametersName = formula.parameters
-  if (referredParametersName !== undefined) {
-    for (const referredParameterName of referredParametersName) {
-      if (encounteredParametersName.has(referredParameterName)) {
-        continue
-      }
-      encounteredParametersName.add(referredParameterName)
-
-      const [referredParameter, referredParameterAncestors] =
-        getParameterWithAncestors(referredParameterName)
-      if (referredParameter === undefined) {
-        continue
-      }
-      yield [referredParameter, referredParameterAncestors]
-    }
-  }
-}
diff --git a/src/lib/sessions.ts b/src/lib/sessions.ts
index caa0e5e5554081c1b37d53ae5be871aa3eb6eed0..f4afccf6bf09d46f78ffeb8741f30fa311a02d16 100644
--- a/src/lib/sessions.ts
+++ b/src/lib/sessions.ts
@@ -1,7 +1,3 @@
-import type { EntityByKey, Metadata, Waterfall } from "@openfisca/ast"
-
-import type { DecompositionCoreByName } from "$lib/decompositions"
-import type { Situation } from "$lib/situations"
 import type { User } from "$lib/users"
 
 export interface Session {
@@ -11,27 +7,19 @@ export interface Session {
   baseUrl: string
   authenticationEnabled: boolean
   childrenKey: string
-  decompositionCoreByName: DecompositionCoreByName
-  decompositionsOptionsVariablesName: Set<string>
   familyEntityKey: string
   hasGithubPersonalAccessToken: boolean
-  entityByKey: EntityByKey
   hiddenEntitiesKeyPlural?: string[]
-  leafParametersName: Set<string>
   matomo?: {
     prependDomain?: boolean
     siteId: number
     subdomains?: string
     url: string
   }
-  metadata: Metadata
   openfiscaRepository: SessionOpenFiscaRepository
-  personEntityKey: string
   portalUrl: string
-  testCases: Situation[]
   title: string
   user?: User
-  waterfalls: Waterfall[]
 }
 
 export interface SessionOpenFiscaRepository {
diff --git a/src/lib/situations.ts b/src/lib/situations.ts
index ae4d2f44c878b6924ba899adb6c1f045194f52e5..441e4656c4553dff98054fc2ceabe1ca78a5fee8 100644
--- a/src/lib/situations.ts
+++ b/src/lib/situations.ts
@@ -1,6 +1,8 @@
 import type { Entity, EntityByKey, GroupEntity, Variable } from "@openfisca/ast"
 import { getRolePersonsIdKey } from "@openfisca/ast"
 
+import testCasesCoreUnknown from "$lib/openfisca/test_cases.json"
+
 export interface Axis {
   count: number
   index?: number
@@ -38,6 +40,8 @@ export type SituationWithAxes = Situation & {
   axes?: Axis[][]
 }
 
+export const testCasesCore = testCasesCoreUnknown as unknown as Situation[]
+
 export function buildTestCasesWithoutNonInputVariables(
   entityByKey: EntityByKey,
   inputInstantsByVariableNameArray: Array<{
diff --git a/src/lib/variables.ts b/src/lib/variables.ts
index 63bda673ebf0b7c8517512ee9d149db9c78e5044..49aee773e62ac8af791a5877a41f603796bb9920 100644
--- a/src/lib/variables.ts
+++ b/src/lib/variables.ts
@@ -1,4 +1,13 @@
-import type { Formula, Reference, Variable } from "@openfisca/ast"
+import type {
+  Formula,
+  Parameter,
+  Reference,
+  Variable,
+  VariableByName,
+} from "@openfisca/ast"
+
+import variableSummaryByNameUnknown from "$lib/openfisca/variables_summaries.json"
+import { getParameter } from "$lib/parameters"
 
 export type VariableValues = boolean[] | number[] | string[]
 
@@ -8,6 +17,9 @@ export interface InstantFormulaAndReferences {
   references: Reference[]
 }
 
+export const variableSummaryByName =
+  variableSummaryByNameUnknown as VariableByName
+
 export function buildInstantFormulaAndReferencesArray(
   variable: Variable,
 ): InstantFormulaAndReferences[] {
@@ -36,24 +48,104 @@ export function buildInstantFormulaAndReferencesArray(
     .map(([, instantFormulaAndReferences]) => instantFormulaAndReferences)
 }
 
-export async function retrieveVariableSummaryByName(
-  baseUrl: string,
-  variablesName: string[],
-): Promise<{ [name: string]: Variable } | undefined> {
-  if (variablesName.length === 0) {
-    return {}
-  }
-  const url = `/variables.json?${new URLSearchParams(
-    variablesName.map((name) => ["name", name]),
-  ).toString()}`
-  const res = await fetch(new URL(url, baseUrl).toString())
-  if (!res.ok) {
-    console.error(
-      `Error ${
-        res.status
-      } while retrieving variables at ${url}\n\n${await res.text()}`,
+export function* iterVariableInputVariables(
+  variable: Variable,
+  date: string,
+  encounteredVariablesName: Set<string> = new Set(),
+): Generator<Variable, void> {
+  const name = variable.name
+  if (encounteredVariablesName.has(name)) {
+    return
+  }
+  encounteredVariablesName.add(name)
+
+  const formulas = variable.formulas
+  if (formulas === undefined) {
+    // Variable is an input variable.
+    yield variable
+    return
+  }
+  const dates = Object.keys(formulas).reverse()
+  let formula = undefined
+  for (const bestDate of dates) {
+    if (bestDate <= date) {
+      formula = formulas[bestDate]
+      break
+    }
+  }
+  if (formula == null) {
+    // No candidate date less than or equal to date found.
+    return
+  }
+  const referredVariablesName = formula.variables
+  if (referredVariablesName === undefined) {
+    return
+  }
+  for (const referredVariableName of referredVariablesName) {
+    const referredVariable = variableSummaryByName[referredVariableName]
+    yield* iterVariableInputVariables(
+      referredVariable,
+      date,
+      encounteredVariablesName,
     )
-    return undefined
   }
-  return await res.json()
+}
+
+export function* iterVariableParameters(
+  variable: Variable,
+  date: string,
+  encounteredParametersName: Set<string> = new Set(),
+  encounteredVariablesName: Set<string> = new Set(),
+): Generator<Parameter, void> {
+  const name = variable.name
+  if (encounteredVariablesName.has(name)) {
+    return
+  }
+  encounteredVariablesName.add(name)
+
+  const formulas = variable.formulas
+  if (formulas === undefined) {
+    return
+  }
+  const dates = Object.keys(formulas).reverse()
+  let formula = undefined
+  for (const bestDate of dates) {
+    if (bestDate <= date) {
+      formula = formulas[bestDate]
+      break
+    }
+  }
+  if (formula == null) {
+    // No candidate date less than or equal to date found.
+    return
+  }
+
+  const referredVariablesName = formula.variables
+  if (referredVariablesName !== undefined) {
+    for (const referredVariableName of referredVariablesName) {
+      const referredVariable = variableSummaryByName[referredVariableName]
+      yield* iterVariableParameters(
+        referredVariable,
+        date,
+        encounteredParametersName,
+        encounteredVariablesName,
+      )
+    }
+  }
+
+  const referredParametersName = formula.parameters
+  if (referredParametersName !== undefined) {
+    for (const referredParameterName of referredParametersName) {
+      if (encounteredParametersName.has(referredParameterName)) {
+        continue
+      }
+      encounteredParametersName.add(referredParameterName)
+
+      const referredParameter = getParameter(referredParameterName)
+      if (referredParameter === undefined) {
+        continue
+      }
+      yield referredParameter
+    }
+  }
 }
diff --git a/src/routes/__error.svelte b/src/routes/__error.svelte
index bdc20c06160a37d2383ec001af8f78b8806bb853..155ea60264bea61f113de62c52aed41a8ba3c1cf 100644
--- a/src/routes/__error.svelte
+++ b/src/routes/__error.svelte
@@ -1,5 +1,5 @@
 <script context="module" lang="ts">
-  import type { ErrorLoadInput, LoadOutput } from "@sveltejs/kit/types/page"
+  import type { ErrorLoadInput, LoadOutput } from "@sveltejs/kit"
 
   export function load({ error, status }: ErrorLoadInput): LoadOutput {
     return {
diff --git a/src/routes/__layout.svelte b/src/routes/__layout.svelte
index 65bb3c2c29fc613e31923383df886c5fc3c017dd..658ef441aa2347fa211bdc14c653d641bdb3af3f 100644
--- a/src/routes/__layout.svelte
+++ b/src/routes/__layout.svelte
@@ -1,7 +1,7 @@
 <script lang="ts">
   import "../app.css"
 
-  import type { EntityByKey, Waterfall } from "@openfisca/ast"
+  import type { Waterfall } from "@openfisca/ast"
   import { setContext } from "svelte"
   import type { Writable } from "svelte/store"
   import { writable } from "svelte/store"
@@ -17,16 +17,20 @@
     EvaluationByName,
   } from "$lib/decompositions"
   import {
-    calculationNames,
     buildDecompositionByNameFromCore,
+    calculationNames,
+    decompositionCoreByName,
     walkDecompositionsCore,
     updateEvaluations,
+    waterfalls,
   } from "$lib/decompositions"
+  import { entityByKey } from "$lib/entities"
   import type { Reform } from "$lib/reforms"
   import type { PopulationWithoutId, Situation } from "$lib/situations"
   import {
     buildTestCasesWithoutNonInputVariables,
     getPopulationReservedKeys,
+    testCasesCore,
   } from "$lib/situations"
   import type { VariableValues } from "$lib/variables"
   import type { WebSocketByName, WebSocketOpenByName } from "$lib/websockets"
@@ -42,22 +46,19 @@
   > = writable({})
   setContext("calculationTokenByName", calculationTokenByName)
 
-  const entityByKey = $session.entityByKey as EntityByKey
-
   const vectorIndexes: Writable<number[]> = writable(
-    new Array($session.testCases.length).fill(0),
+    new Array(testCasesCore.length).fill(0),
   )
   setContext("vectorIndexes", vectorIndexes)
 
   const vectorLength = writable(1)
   setContext("vectorLength", vectorLength)
 
-  const waterfalls = $session.waterfalls
   let waterfall = writable(waterfalls[0])
   setContext("waterfall", waterfall)
 
   const decompositionByName = writable(
-    buildDecompositionByNameFromCore($session.decompositionCoreByName),
+    buildDecompositionByNameFromCore(decompositionCoreByName),
   )
   setContext("decompositionByName", decompositionByName)
 
@@ -67,7 +68,7 @@
     Object.fromEntries(
       calculationNames.map((calculationName) => [
         calculationName,
-        new Array($session.testCases.length)
+        new Array(testCasesCore.length)
           .fill(null)
           .map((_, situationIndex) =>
             updateEvaluations(
@@ -90,7 +91,7 @@
     Array<{
       [name: string]: Set<string>
     }>
-  > = writable(extractInputInstantsFromTestCases($session.testCases))
+  > = writable(extractInputInstantsFromTestCases(testCasesCore))
   setContext(
     "inputInstantsByVariableNameArray",
     inputInstantsByVariableNameArray,
@@ -101,7 +102,7 @@
   // Note: Duplicates are removed from nonVirtualDecompositionsName, because a variable name
   // may appear more than once in decomposition.
   const nonVirtualDecompositionsName = computeNonVirtualDecompositionsName(
-    $session.decompositionCoreByName,
+    decompositionCoreByName,
     waterfalls,
   )
   setContext("nonVirtualDecompositionsName", nonVirtualDecompositionsName)
@@ -137,13 +138,13 @@
       try {
         testCasesValue = JSON.parse(testCasesJson)
       } catch {
-        testCasesValue = $session.testCases
+        testCasesValue = testCasesCore
       }
     } else {
-      testCasesValue = $session.testCases
+      testCasesValue = testCasesCore
     }
   } else {
-    testCasesValue = $session.testCases
+    testCasesValue = testCasesCore
   }
   const testCases = writable(testCasesValue)
   setContext("testCases", testCases)
@@ -180,7 +181,7 @@
       "testCases",
       JSON.stringify(
         buildTestCasesWithoutNonInputVariables(
-          $session.entityByKey,
+          entityByKey,
           $inputInstantsByVariableNameArray,
           $testCases,
         ),
diff --git a/src/routes/entities.svelte b/src/routes/entities.svelte
index 8a31e670ec6ffe652968c1d33b9548cbf609cac2..59eb5fd31beaa729ba1cc7f250097999bccf3db7 100644
--- a/src/routes/entities.svelte
+++ b/src/routes/entities.svelte
@@ -1,7 +1,7 @@
 <script lang="ts">
   import { session } from "$app/stores"
 
-  const entityByKey = $session.entityByKey
+  import { entityByKey } from "$lib/entities"
 </script>
 
 <svelte:head>
diff --git a/src/routes/index.svelte b/src/routes/index.svelte
index 6939ccb7b3d97c68068d2b3156466d72efe13e1b..0c39b26576fa9204ed503fd10d3fbf97ee5bbddf 100644
--- a/src/routes/index.svelte
+++ b/src/routes/index.svelte
@@ -36,7 +36,9 @@
     labelFromCalculationName,
     updateEvaluations,
     updateVectorIndex,
+    waterfalls,
   } from "$lib/decompositions"
+  import { entityByKey } from "$lib/entities"
   import type { Reform } from "$lib/reforms"
   import type {
     Axis,
@@ -47,6 +49,7 @@
   import {
     buildTestCasesWithoutNonInputVariables,
     getPopulationReservedKeys,
+    testCasesCore,
   } from "$lib/situations"
   import type { SelfTargetAProps } from "$lib/urls"
   import type { WebSocketByName, WebSocketOpenByName } from "$lib/websockets"
@@ -112,7 +115,6 @@
   ) as Writable<{ [name in CalculationName]?: string }>
   const vectorIndexes = getContext("vectorIndexes") as Writable<number[]>
   const vectorLength = getContext("vectorLength") as Writable<number>
-  const waterfalls = $session.waterfalls
   const webSocketByName = getContext("webSocketByName") as Writable<
     WebSocketByName | undefined
   >
@@ -381,7 +383,7 @@
 
   function reset(): void {
     $reform = {}
-    $testCases = $session.testCases
+    $testCases = testCasesCore
     if (
       calculationNames.some(
         (calculationName) => !$requestedCalculationsName.has(calculationName),
@@ -417,7 +419,7 @@
       body: JSON.stringify({
         reform: $reform,
         testCases: buildTestCasesWithoutNonInputVariables(
-          $session.entityByKey,
+          entityByKey,
           $inputInstantsByVariableNameArray,
           $testCases,
         ),
@@ -442,7 +444,7 @@
   function submit(requestedCalculationsName: Set<CalculationName>) {
     // Aggregate every situations into a single one without calculated variables.
     const aggregatedSituation: SituationWithAxes = {}
-    const entities = Object.values($session.entityByKey as EntityByKey)
+    const entities = Object.values(entityByKey as EntityByKey)
     for (const [situationIndex, situation] of $testCases.entries()) {
       const inputInstantsByVariableName =
         $inputInstantsByVariableNameArray[situationIndex]
diff --git a/src/routes/parameters/[parameter]/edit.svelte b/src/routes/parameters/[parameter]/edit.svelte
index 75155a718f55f6366eb17b4bdd1b67490d902b6b..458df8c3b219c8c3fa72b5f5b922d3dcf4a56c13 100644
--- a/src/routes/parameters/[parameter]/edit.svelte
+++ b/src/routes/parameters/[parameter]/edit.svelte
@@ -3,14 +3,13 @@
   import type { Metadata } from "@openfisca/ast"
   import {
     auditRawParameterToEditable,
-    improveParameterWithAncestors,
     iterParameterAncestors,
     ParameterClass,
   } from "@openfisca/ast"
-  import type { LoadInput, LoadOutput } from "@sveltejs/kit/types/page"
+  import type { LoadInput, LoadOutput } from "@sveltejs/kit"
   import yaml from "js-yaml"
 
-  import { labelFromParameterClass } from "$lib/parameters"
+  import { getParameter, labelFromParameterClass } from "$lib/parameters"
   import type { SessionOpenFiscaRepository } from "$lib/sessions"
 
   export async function load({
@@ -19,18 +18,13 @@
     session,
   }: LoadInput): Promise<LoadOutput> {
     const { parameter: name } = page.params
-    const url = `/parameters/${name}.json`
-    const res = await fetch(url)
-    if (!res.ok) {
+    const processedParameter = getParameter(name)
+    if (processedParameter === undefined) {
       return {
-        status: res.status,
-        error: new Error(`Could not load ${url}`),
+        status: 404,
+        error: new Error(`Parameter "${name}" not found`),
       }
     }
-    const processedParameterWithAncestors = await res.json()
-    const processedParameter = improveParameterWithAncestors(
-      processedParameterWithAncestors,
-    )
 
     let unprocessedParameterUrl = newParameterRepositoryRawUrl(
       session.metadata,
diff --git a/src/routes/parameters/[parameter]/index.json.ts b/src/routes/parameters/[parameter]/index.json.ts
index eddda26537f32e9491b4396f4739869020a94947..516457d8df94242421e8c9d339bf71fcb300972a 100644
--- a/src/routes/parameters/[parameter]/index.json.ts
+++ b/src/routes/parameters/[parameter]/index.json.ts
@@ -4,37 +4,17 @@ import {
   auditEditableParameter,
   convertEditableParameterToRaw,
   ParameterClass,
-  parameterWithoutChildren,
   yamlFromRawParameter,
 } from "@openfisca/ast"
 import type { RequestHandler } from "@sveltejs/kit"
 import { randomBytes } from "crypto"
 
+import { metadata } from "$lib/metadata"
+import { getParameter } from "$lib/parameters"
 import config from "$lib/server/config"
-import { metadata } from "$lib/server/metadata"
-import { getParameterWithAncestors } from "$lib/server/parameters"
 
 const { githubPersonalAccessToken, openfiscaRepository } = config
 
-export const get: RequestHandler = ({ params }) => {
-  const { parameter: name } = params
-  const [parameter, ancestors] = getParameterWithAncestors(name)
-  if (parameter === undefined) {
-    return { body: null, status: 404 }
-  }
-  return {
-    body: {
-      // Remove children from ancestors, because we don't want to send
-      // the full tree.
-      ancestors: ancestors.map(
-        (ancestor) =>
-          parameterWithoutChildren(ancestor) as unknown as JsonValue,
-      ),
-      parameter: parameter as unknown as JsonValue,
-    },
-  }
-}
-
 export const put: RequestHandler = async ({ body, params }) => {
   if (githubPersonalAccessToken === undefined) {
     return {
@@ -49,7 +29,7 @@ export const put: RequestHandler = async ({ body, params }) => {
   }
 
   const { parameter: name } = params
-  const [parameter] = getParameterWithAncestors(name)
+  const parameter = getParameter(name)
   if (parameter === undefined) {
     return { body: null, status: 404 }
   }
diff --git a/src/routes/parameters/[parameter]/index.svelte b/src/routes/parameters/[parameter]/index.svelte
index 5db78418ecef9905c0311e0d7cb56e148228465e..42433b6da9c280d784a54adbedd731170768ba12 100644
--- a/src/routes/parameters/[parameter]/index.svelte
+++ b/src/routes/parameters/[parameter]/index.svelte
@@ -1,21 +1,20 @@
 <script context="module" lang="ts">
-  import { improveParameterWithAncestors } from "@openfisca/ast"
-  import type { LoadInput, LoadOutput } from "@sveltejs/kit/types/page"
+  import type { LoadInput, LoadOutput } from "@sveltejs/kit"
 
-  export async function load({ fetch, page }: LoadInput): Promise<LoadOutput> {
+  import { getParameter } from "$lib/parameters"
+
+  export function load({ page }: LoadInput): LoadOutput {
     const { parameter: name } = page.params
-    const url = `/parameters/${name}.json`
-    const res = await fetch(url)
-    if (!res.ok) {
+    const parameter = getParameter(name)
+    if (parameter === undefined) {
       return {
-        status: res.status,
-        error: new Error(`Could not load ${url}`),
+        status: 404,
+        error: new Error(`Parameter "${name}" not found`),
       }
     }
-    const parameterWithAncestors = await res.json()
     return {
       props: {
-        parameter: improveParameterWithAncestors(parameterWithAncestors),
+        parameter,
       },
     }
   }
@@ -40,8 +39,7 @@
 
 <a
   href="/"
-  class="inline-flex items-center bg-gray-200 my-5 p-1 pr-2 text-xs rounded
-text-black shadow-md hover:bg-gray-400"
+  class="inline-flex items-center bg-gray-200 my-5 p-1 pr-2 text-xs rounded text-black shadow-md hover:bg-gray-400"
 >
   <!-- material icons - Arrow Back -->
   <svg
diff --git a/src/routes/parameters/index.json.ts b/src/routes/parameters/index.json.ts
deleted file mode 100644
index 550cadf9346216f788dba8f8448e859e3d79d97a..0000000000000000000000000000000000000000
--- a/src/routes/parameters/index.json.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import type { JsonValue } from "@openfisca/ast"
-import type { RequestHandler } from "@sveltejs/kit"
-
-import { parameters } from "$lib/server/parameters"
-
-export const get: RequestHandler = () => {
-  return { body: parameters as unknown as JsonValue }
-}
diff --git a/src/routes/parameters/index.svelte b/src/routes/parameters/index.svelte
index 5cc0f12c57b917358e3c4071bac1520850d1f074..12887cf6d3fd7b80776984ae5249b676cc557a03 100644
--- a/src/routes/parameters/index.svelte
+++ b/src/routes/parameters/index.svelte
@@ -1,33 +1,10 @@
-<script context="module" lang="ts">
-  import type { NodeParameter, Parameter } from "@openfisca/ast"
-  import { improveParameter } from "@openfisca/ast"
-  import type { LoadInput, LoadOutput } from "@sveltejs/kit/types/page"
-
-  export async function load({ fetch }: LoadInput): Promise<LoadOutput> {
-    const url = "/parameters.json"
-    const res = await fetch(url)
-    if (!res.ok) {
-      return {
-        status: res.status,
-        error: new Error(`Could not load ${url}`),
-      }
-    }
-    const rootParameter = await res.json()
-    improveParameter(null, rootParameter)
-    return {
-      props: {
-        rootParameter,
-      },
-    }
-  }
-</script>
-
 <script lang="ts">
+  import type { Parameter } from "@openfisca/ast"
+
   import { goto } from "$app/navigation"
   import { page, session } from "$app/stores"
   import ParametersSearch from "$lib/components/parameters/ParametersSearch.svelte"
-
-  export let rootParameter: NodeParameter
+  import { rootParameter } from "$lib/parameters"
 
   let initialTerm: string | undefined = undefined
 
diff --git a/src/routes/simulation.svelte b/src/routes/simulation.svelte
index 655bd81a0e6b25775c1ea7248830702ba80f5f4e..1695385e0e26d01cdbee81c89324bfed261c6ea3 100644
--- a/src/routes/simulation.svelte
+++ b/src/routes/simulation.svelte
@@ -1,5 +1,5 @@
 <script context="module" lang="ts">
-  import type { LoadOutput } from "@sveltejs/kit/types/page"
+  import type { LoadOutput } from "@sveltejs/kit"
   export function load(): LoadOutput {
     return {
       redirect: "/",
diff --git a/src/routes/simulations/[simulation].svelte b/src/routes/simulations/[simulation].svelte
index 525c19c87d5c89ab481719fc66d59d6488522986..2912e896040c51a00363568f137eca8dc1461870 100644
--- a/src/routes/simulations/[simulation].svelte
+++ b/src/routes/simulations/[simulation].svelte
@@ -1,5 +1,5 @@
 <script context="module" lang="ts">
-  import type { LoadInput, LoadOutput } from "@sveltejs/kit/types/page"
+  import type { LoadInput, LoadOutput } from "@sveltejs/kit"
 
   export async function load({ fetch, page }: LoadInput): Promise<LoadOutput> {
     const { simulation: token } = page.params
diff --git a/src/routes/variables/[variable]/index.json.ts b/src/routes/variables/[variable]/index.json.ts
index 8dde6864e322599142e0c262531a169a6e85340e..8a897082b4040e3bd244fa2fe54c0d654f9c768e 100644
--- a/src/routes/variables/[variable]/index.json.ts
+++ b/src/routes/variables/[variable]/index.json.ts
@@ -5,12 +5,12 @@ import sanitizeFilename from "sanitize-filename"
 
 import config from "$lib/server/config"
 
-const { jsonDir } = config
+const { openfiscaDir } = config
 
 export const get: RequestHandler = async ({ params }) => {
   const { variable: name } = params
   const variableFilePath = path.join(
-    jsonDir,
+    openfiscaDir,
     "variables",
     `${sanitizeFilename(name)}.json`,
   )
diff --git a/src/routes/variables/[variable]/index.svelte b/src/routes/variables/[variable]/index.svelte
index 341e85dbc55065afd9d30df47cc0af15da46f21f..6b049cb8124667ce45ab16116f5abd66a5302aac 100644
--- a/src/routes/variables/[variable]/index.svelte
+++ b/src/routes/variables/[variable]/index.svelte
@@ -1,5 +1,5 @@
 <script context="module" lang="ts">
-  import type { LoadInput, LoadOutput } from "@sveltejs/kit/types/page"
+  import type { LoadInput, LoadOutput } from "@sveltejs/kit"
 
   export async function load({ fetch, page }: LoadInput): Promise<LoadOutput> {
     const { variable: name } = page.params
diff --git a/src/routes/variables/[variable]/inputs/[date].json.ts b/src/routes/variables/[variable]/inputs/[date].json.ts
deleted file mode 100644
index 242be14afb044ab08f1b9c61deb4c2d581364ee8..0000000000000000000000000000000000000000
--- a/src/routes/variables/[variable]/inputs/[date].json.ts
+++ /dev/null
@@ -1,162 +0,0 @@
-import type { Audit } from "@auditors/core"
-import {
-  auditArray,
-  auditFunction,
-  auditOptions,
-  auditRequire,
-  auditSetNullish,
-  auditStringToBoolean,
-  auditTest,
-  auditTrimString,
-  cleanAudit,
-} from "@auditors/core"
-import type { JsonValue } from "@openfisca/ast"
-import type { RequestHandler } from "@sveltejs/kit"
-import fs from "fs-extra"
-import path from "path"
-import sanitizeFilename from "sanitize-filename"
-
-import { walkDecompositionsCoreName } from "$lib/decompositions"
-import config from "$lib/server/config"
-import { decompositionCoreByName, waterfalls } from "$lib/server/decompositions"
-import { iterVariableInputVariables } from "$lib/server/variables"
-
-const { jsonDir } = config
-
-function auditVariableInputsQuery(
-  audit: Audit,
-  query: URLSearchParams,
-): [unknown, unknown] {
-  if (query == null) {
-    return [query, null]
-  }
-  if (!(query instanceof URLSearchParams)) {
-    return audit.unexpectedType(query, "URLSearchParams")
-  }
-
-  const data: { [key: string]: unknown } = {}
-  // @ts-expect-error: urlSearchParams.entries() exists both on browsers & Node.
-  for (const [key, value] of query.entries()) {
-    let values = data[key] as string[] | undefined
-    if (values === undefined) {
-      values = data[key] = []
-    }
-    values.push(value)
-  }
-  const errors: { [key: string]: unknown } = {}
-  const remainingKeys = new Set(Object.keys(data))
-
-  audit.attribute(
-    data,
-    "filter_decomposition",
-    true,
-    errors,
-    remainingKeys,
-    auditArray(auditTrimString, auditStringToBoolean),
-    auditTest(
-      (values) => values.length <= 1,
-      "Parameter must be present only once in query",
-    ),
-    auditFunction((value) => value[0]),
-    auditSetNullish(false),
-  )
-  audit.attribute(
-    data,
-    "waterfall",
-    true,
-    errors,
-    remainingKeys,
-    auditArray(auditOptions(waterfalls.map(({ name }) => name))),
-    auditTest(
-      (values) => values.length <= 1,
-      "Parameter must be present only once in query",
-    ),
-    auditFunction((value) => value[0]),
-  )
-
-  if (
-    errors.filter_decomposition === undefined &&
-    data.filter_decomposition &&
-    errors.waterfall === undefined
-  ) {
-    audit.attribute(
-      data,
-      "waterfall",
-      true,
-      errors,
-      remainingKeys,
-      auditRequire,
-    )
-  }
-
-  return audit.reduceRemaining(data, errors, remainingKeys, auditSetNullish({}))
-}
-
-export const get: RequestHandler = async ({
-  path: requestPath,
-  query: requestQuery,
-  params,
-}) => {
-  const [query, queryError] = auditVariableInputsQuery(cleanAudit, requestQuery)
-  if (queryError !== null) {
-    console.error(
-      `Error in ${requestPath} query:\n${JSON.stringify(
-        query,
-        null,
-        2,
-      )}\n\nError:\n${JSON.stringify(queryError, null, 2)}`,
-    )
-    return {
-      status: 400,
-      body: {
-        error: {
-          code: 400,
-          details: queryError as JsonValue,
-          message: "Invalid query",
-          path: requestPath,
-        },
-        query: query as JsonValue,
-      },
-    }
-  }
-  const {
-    filter_decomposition: filterDecomposition,
-    waterfall: waterfallName,
-  } = query as {
-    filter_decomposition: boolean
-    waterfall?: string
-  }
-
-  const { date, variable: name } = params
-  const variableFilePath = path.join(
-    jsonDir,
-    "variables",
-    `${sanitizeFilename(name)}.json`,
-  )
-  if (!(await fs.pathExists(variableFilePath))) {
-    return { body: null, status: 404 }
-  }
-  const variable = await fs.readJson(variableFilePath)
-
-  let ignoreVariablesName: Set<string>
-  if (filterDecomposition) {
-    const waterfall = waterfalls.find(({ name }) => name === waterfallName)
-    ignoreVariablesName = new Set(
-      walkDecompositionsCoreName(
-        decompositionCoreByName,
-        waterfall.name,
-        waterfall.root,
-        false,
-      ),
-    )
-    ignoreVariablesName.delete(variable.name)
-  } else {
-    ignoreVariablesName = new Set()
-  }
-
-  return {
-    body: [
-      ...iterVariableInputVariables(variable, date, ignoreVariablesName),
-    ] as unknown as JsonValue,
-  }
-}
diff --git a/src/routes/variables/[variable]/inputs/[date].svelte b/src/routes/variables/[variable]/inputs/[date].svelte
index 387e9376ec3bbff273ec78745251a29599016753..0ec2089b3d4b9f49f2c750295d865daa909ec9d5 100644
--- a/src/routes/variables/[variable]/inputs/[date].svelte
+++ b/src/routes/variables/[variable]/inputs/[date].svelte
@@ -1,51 +1,25 @@
 <script context="module" lang="ts">
-  import type { LoadInput, LoadOutput } from "@sveltejs/kit/types/page"
+  import type { LoadInput, LoadOutput } from "@sveltejs/kit"
 
-  export async function load({ fetch, page }: LoadInput): Promise<LoadOutput> {
+  import {
+    iterVariableInputVariables,
+    variableSummaryByName,
+  } from "$lib/variables"
+
+  export function load({ page }: LoadInput): LoadOutput {
     const { date, variable: name } = page.params
-    const results = await Promise.all([
-      (async () => {
-        const url = `/variables/${name}.json`
-        const res = await fetch(url)
-        if (!res.ok) {
-          return {
-            status: res.status,
-            error: new Error(`Could not load ${url}`),
-          }
-        }
-        return {
-          props: {
-            variable: await res.json(),
-          },
-        }
-      })(),
-      (async () => {
-        const url = `/variables/${name}/inputs/${date}.json`
-        const res = await fetch(url)
-        if (!res.ok) {
-          return {
-            status: res.status,
-            error: new Error(`Could not load ${url}`),
-          }
-        }
-        return {
-          props: {
-            inputs: await res.json(),
-          },
-        }
-      })(),
-    ])
-    const firstResultWithError = results.find(
-      ({ error }) => error !== undefined,
-    )
-    if (firstResultWithError !== undefined) {
-      return firstResultWithError
+    const variable = variableSummaryByName[name]
+    if (variable === undefined) {
+      return {
+        status: 404,
+        error: new Error(`Variable "${name}" not found`),
+      }
     }
+    const inputs = [...iterVariableInputVariables(variable, date, new Set())]
     return {
       props: {
-        ...Object.fromEntries(
-          [].concat(...results.map(({ props }) => Object.entries(props))),
-        ),
+        inputs,
+        variable,
       },
     }
   }
diff --git a/src/routes/variables/[variable]/parameters/[date].json.ts b/src/routes/variables/[variable]/parameters/[date].json.ts
deleted file mode 100644
index 9a41a2b9ef030842db3adec4bbb81f61234e63c6..0000000000000000000000000000000000000000
--- a/src/routes/variables/[variable]/parameters/[date].json.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import type { JsonValue } from "@openfisca/ast"
-import { parameterWithoutChildren } from "@openfisca/ast"
-import type { RequestHandler } from "@sveltejs/kit"
-import fs from "fs-extra"
-import path from "path"
-import sanitizeFilename from "sanitize-filename"
-
-import config from "$lib/server/config"
-import { iterVariableParametersWithAncestors } from "$lib/server/variables"
-
-const { jsonDir } = config
-
-export const get: RequestHandler = async ({ params }) => {
-  const { date, variable: name } = params
-  const variableFilePath = path.join(
-    jsonDir,
-    "variables",
-    `${sanitizeFilename(name)}.json`,
-  )
-  if (!(await fs.pathExists(variableFilePath))) {
-    return { body: null, status: 404 }
-  }
-  const variable = await fs.readJson(variableFilePath)
-  return {
-    body: [...iterVariableParametersWithAncestors(variable, date)].map(
-      ([parameter, ancestors]) => ({
-        // Remove children from ancestors, because we don't want to send
-        // the full tree.
-        ancestors: ancestors.map(
-          (ancestor) =>
-            parameterWithoutChildren(ancestor) as unknown as JsonValue,
-        ),
-        parameter: parameter as unknown as JsonValue,
-      }),
-    ),
-  }
-}
diff --git a/src/routes/variables/[variable]/parameters/[date].svelte b/src/routes/variables/[variable]/parameters/[date].svelte
index 3c2f1470b55a413803356dc3c772475f76ddd0e0..09dd88b73f91c93cbbdf83148431af452a3ba0d9 100644
--- a/src/routes/variables/[variable]/parameters/[date].svelte
+++ b/src/routes/variables/[variable]/parameters/[date].svelte
@@ -1,55 +1,23 @@
 <script context="module" lang="ts">
-  import { improveParameterWithAncestors } from "@openfisca/ast"
-  import type { LoadInput, LoadOutput } from "@sveltejs/kit/types/page"
+  import type { LoadInput, LoadOutput } from "@sveltejs/kit"
 
-  export async function load({ fetch, page }: LoadInput): Promise<LoadOutput> {
+  import { iterVariableParameters, variableSummaryByName } from "$lib/variables"
+
+  export function load({ page }: LoadInput): LoadOutput {
     const { date, variable: name } = page.params
-    const results = await Promise.all([
-      (async () => {
-        const url = `/variables/${name}.json`
-        const res = await fetch(url)
-        if (!res.ok) {
-          return {
-            status: res.status,
-            error: new Error(`Could not load ${url}`),
-          }
-        }
-        return {
-          props: {
-            variable: await res.json(),
-          },
-        }
-      })(),
-      (async () => {
-        const url = `/variables/${name}/parameters/${date}.json`
-        const res = await fetch(url)
-        if (!res.ok) {
-          return {
-            status: res.status,
-            error: new Error(`Could not load ${url}`),
-          }
-        }
-        const parametersWithAncestors = await res.json()
-        return {
-          props: {
-            parameters: parametersWithAncestors.map(
-              improveParameterWithAncestors,
-            ),
-          },
-        }
-      })(),
-    ])
-    const firstResultWithError = results.find(
-      ({ error }) => error !== undefined,
-    )
-    if (firstResultWithError !== undefined) {
-      return firstResultWithError
+    const variable = variableSummaryByName[name]
+    if (variable === undefined) {
+      return {
+        status: 404,
+        error: new Error(`Variable "${name}" not found`),
+      }
     }
+    const parameters = [...iterVariableParameters(variable, date)]
+
     return {
       props: {
-        ...Object.fromEntries(
-          [].concat(...results.map(({ props }) => Object.entries(props))),
-        ),
+        variable,
+        parameters,
       },
     }
   }
diff --git a/src/routes/variables/index.json.ts b/src/routes/variables/index.json.ts
deleted file mode 100644
index 031721909778f10ef008a347f6df479b38501664..0000000000000000000000000000000000000000
--- a/src/routes/variables/index.json.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-import type { Audit } from "@auditors/core"
-import {
-  auditArray,
-  auditOptions,
-  auditSetNullish,
-  auditTrimString,
-  cleanAudit,
-} from "@auditors/core"
-import type { JsonValue } from "@openfisca/ast"
-import type { RequestHandler } from "@sveltejs/kit"
-
-import { variableSummaryByName } from "$lib/server/variables"
-
-const variablesName = Object.keys(variableSummaryByName)
-
-function auditVariablesQuery(
-  audit: Audit,
-  query: URLSearchParams,
-): [unknown, unknown] {
-  if (query == null) {
-    return [query, null]
-  }
-  if (!(query instanceof URLSearchParams)) {
-    return audit.unexpectedType(query, "URLSearchParams")
-  }
-
-  const data: { [key: string]: unknown } = {}
-  // @ts-expect-error: urlSearchParams.entries() exists both on browsers & Node.
-  for (const [key, value] of query.entries()) {
-    let values = data[key] as string[] | undefined
-    if (values === undefined) {
-      values = data[key] = []
-    }
-    values.push(value)
-  }
-  const errors: { [key: string]: unknown } = {}
-  const remainingKeys = new Set(Object.keys(data))
-
-  audit.attribute(
-    data,
-    "name",
-    true,
-    errors,
-    remainingKeys,
-    auditArray(auditTrimString, auditOptions(variablesName)),
-  )
-
-  return audit.reduceRemaining(data, errors, remainingKeys, auditSetNullish({}))
-}
-
-export const get: RequestHandler = async ({
-  path: requestPath,
-  query: requestQuery,
-}) => {
-  const [query, queryError] = auditVariablesQuery(cleanAudit, requestQuery)
-  if (queryError !== null) {
-    console.error(
-      `Error in ${requestPath} query:\n${JSON.stringify(
-        query,
-        null,
-        2,
-      )}\n\nError:\n${JSON.stringify(queryError, null, 2)}`,
-    )
-    return {
-      status: 400,
-      body: {
-        error: {
-          code: 400,
-          details: queryError as JsonValue,
-          message: "Invalid query",
-          path: requestPath,
-        },
-        query: query as JsonValue,
-      },
-    }
-  }
-  const { name: names } = query as {
-    name?: string[]
-  }
-
-  if (names === undefined) {
-    return { body: variableSummaryByName as unknown as JsonValue }
-  }
-
-  const requestedVariableSummaryByName = Object.fromEntries(
-    Object.entries(variableSummaryByName).filter(([name]) =>
-      names.includes(name),
-    ),
-  )
-  return { body: requestedVariableSummaryByName as unknown as JsonValue }
-}
diff --git a/src/routes/variables/index.svelte b/src/routes/variables/index.svelte
index 0dde097aa5bb536f89f2d41cbbc07ca8c4ec6ca3..9f2d46a57cd8181c7ac3f64a1fe6ebc6b487ad60 100644
--- a/src/routes/variables/index.svelte
+++ b/src/routes/variables/index.svelte
@@ -1,29 +1,6 @@
-<script context="module" lang="ts">
-  import type { LoadInput, LoadOutput } from "@sveltejs/kit/types/page"
-
-  export async function load({ fetch }: LoadInput): Promise<LoadOutput> {
-    const url = "/variables.json"
-    const res = await fetch(url)
-    if (!res.ok) {
-      return {
-        status: res.status,
-        error: new Error(`Could not load ${url}`),
-      }
-    }
-    return {
-      props: {
-        variableSummaryByName: await res.json(),
-      },
-    }
-  }
-</script>
-
 <script lang="ts">
-  import type { VariableByName } from "@openfisca/ast"
-
   import { session } from "$app/stores"
-
-  export let variableSummaryByName: VariableByName
+  import { variableSummaryByName } from "$lib/variables"
 </script>
 
 <svelte:head>
diff --git a/svelte.config.js b/svelte.config.js
index 070e68dff95e9d7ca4e2952a019aababfb5eba85..5165f6763b1301bff9a0e66957dad7c1f904a021 100644
--- a/svelte.config.js
+++ b/svelte.config.js
@@ -15,6 +15,11 @@ const config = {
     target: "#svelte",
 
     vite: {
+      build: {
+        // Increase size of chunks to 3 MB, to be able to import
+        // JSON files extracted from OpenFisca country package.
+        chunkSizeWarningLimit: 3072,
+      },
       optimizeDeps: {
         // See https://svelte-modals.mattjennings.io/
         // and https://github.com/sveltejs/vite-plugin-svelte/issues/124.