Loading workbench page
Fetching primary parquet sources and computing exhibits.
Fetching primary parquet sources and computing exhibits.
Every page in the /x tree cites the paper behind the method and the data vintage behind the number. This page is the consolidated reference: what we use, where it comes from, how we compute it, what units it is carried in, and which papers the estimators are from.
Nothing on this page queries a database. It is prose and references. The workbench's discipline is that each figure elsewhere in the tree embeds the SQL that produced it, next to the literature behind the method. Readers who want to audit a number can read the SQL, re-run it against the Parquet files, and cross-check the formula against the cited paper.
All data is open or redistributable. Upstream URLs and licenses are listed below. Local Parquet mirrors are regenerated from upstream releases on a scheduled cadence.
Release: CEPII BACI 202601 (retrieved 2026-06-01). Coverage: 238 reporter/partner territories, 5,115 HS6 product codes, years 1996-2024. Reconciled mirror flows, f.o.b. basis, values in thousands of current USD, quantities in metric tons. Underlying source: UN Comtrade. The reconciliation procedure is documented in Gaulier & Zignago (2010). Used on: world, country, product, bilateral, rankings, complexity, product-space, gravity, tariffs, quality, structural-change, supply-chain, food-security, historical.
URL: cepii.fr/CEPII/en/bdd_modele/bdd_modele_item.asp?id=37. License: CEPII open license, citation required.
Local release: not verified. Country pairs with distance (weighted by population), contiguity, common official language, colonial history, RTA dummies, and GDP series. Used on: gravity, bilateral, trade-costs. URL: cepii.fr/CEPII/en/bdd_modele/bdd_modele_item.asp?id=8. License: CEPII open.
Release: coverage 1827-2014. Bilateral exports and imports reconstructed from customs records and trade yearbooks, in current USD. Used on: historical, long-run globalization figures. Primary reference: Fouquin & Hugot (2016). URL: cepii.fr/CEPII/en/bdd_modele/bdd_modele_item.asp?id=32.
Bilateral ad-valorem trade-cost equivalents derived from Novy's (2013) inverted-gravity identity. Sector breakdown (agriculture, manufacturing) and time series 1995-present. Used on: trade-costs. URL: unescap.org/resources/escap-world-bank-trade-cost-database. License: open data, citation of Arvis, Duval, Shepherd, Utoktham & Raj (2016).
UNCTAD TRAINS tariff schedules through the World Bank's WITS portal. Simple and trade-weighted averages at HS6 by reporter, partner, year. Used on: tariffs, supply-chain cost decomposition, bilateral margins. URL: wits.worldbank.org. License: WITS terms, citation required.
UNCTAD MAST-classified non-tariff measures (SPS, TBT, quantitative restrictions, price controls) aggregated to country-product intensity and product-level coverage ratios. Used on: ntm. URL: trains.unctad.org. Primary reference: UNCTAD (2019) MAST handbook.
World Development Indicators, ~1,400 indicators, 217 economies. Used on: wdi, country macro panels, gravity regressors. URL: databank.worldbank.org/source/world-development-indicators. License: CC-BY-4.0.
Monthly and annual international commodity prices, 71 series, 1960-present. Used on: commodities, food-security, terms-of-trade decompositions. URL: worldbank.org/en/research/commodity-markets. License: CC-BY-4.0.
Balance-of-Payments (BPM6), International Financial Statistics, World Economic Outlook, and International Investment Position. Used on: macro country profiles (current account, REER, NEER, IIP, terms of trade), Feldstein-Horioka tests. URL: data.imf.org. License: IMF open data.
FAO trade matrix, food-balance sheets, and production data. Used on: food-security, agricultural trade, SSR calculations. URL: fao.org/faostat. License: CC-BY-4.0. Values in 1,000 USD (multiply by 1000 for display).
OECD Trade in Value Added database, 2023 edition. Decomposes gross exports into domestic and foreign value added, backward and forward participation in global value chains, and upstreamness. Reports at the country-industry level for 77 economies and 45 ISIC Rev.4 industries, 1995-2020. Used on: gvc, structural-change, upstreamness computations. URL: oecd.org/sti/ind/measuring-trade-in-value-added.htm. License: OECD terms, free for research with attribution. Primary reference: Koopman, Wang & Wei (2014) AER.
Each method below is stated as a formula, tagged with the primary paper, and linked to the pages where it appears. Notation: c = country, p = product (HS6), t = year, xcpt = exports of product p by country c in year t.
RCAcp = (xcp / Σp′ xcp′) / (Σc′ xc′p / Σc′p′ xc′p′). A country has revealed comparative advantage in product pwhen RCA > 1. Dimensionless ratio; do not currency-format. Primary reference: Balassa (1965). Appears on: country, product, complexity, product-space, rankings, structural-change.
Build the binary country-product matrix Mcp = 1[RCAcp ≥ 1]. ECI is the second eigenvector of the country-country projection M·diag(1/kp)·MT·diag(1/kc) where kc is country diversification and kpis product ubiquity. Standardized to zero mean, unit variance. The eigenvector construction is from the Atlas of Economic Complexity (Hausmann et al. 2011); it is equivalent to the method of reflections introduced by Hidalgo & Hausmann (2009) PNAS (Mealy, Farmer & Teytelboym 2019, Science Advances). Appears on: country, complexity, rankings, structural-change.
For the core HS96 catalogue, PCI is the product-side analogue of ECI: the second eigenvector of the product-product projection of the same Mmatrix. For post-HS96 extended products, the implementation uses a proxy: mean ECI among exporters with dimensionless RCA ≥ 1. These extended values are appended to the eigenvector core before ranking, so the combined catalogue rank crosses HS nomenclature revisions and is neither a revision-pure product universe nor a homogeneous estimator. As a dated example, the 2024 combined rank has 6,266 products: 4,762 HS96 core codes and 1,504 extension-only codes. The core PCI is zero-centered, and all PCI values are signed. Negative values are valid for low-complexity products, so never filter or take their absolute value.Primary reference for the core method: the Atlas of Economic Complexity (Hausmann et al. 2011), building on Hidalgo & Hausmann (2009). Appears on: product, country basket plots, rankings, quality.
φpp′ = min(P(RCAp | RCAp′), P(RCAp′ | RCAp)). Conditional co-export probability between two products across countries; proxies how similar the underlying productive capabilities are. Stored as a symmetric upper-triangle. Primary reference: Hidalgo, Klinger, Barabási & Hausmann (2007) Science. Appears on: product-space, country basket frontier.
HHI = Σi si2, with shares si summing to one. Range [1/N, 1]. The effective number of equally-sized lines is Ne = 1/HHI. Historical 2010 DOJ/FTC thresholds: unconcentrated < 0.15, moderately concentrated 0.15-0.25, highly concentrated > 0.25. Primary reference: Adelman (1969). Appears on: country (export diversification), product (supplier concentration), supply-chain. The 2023 guidelines instead use a highly concentrated threshold above 0.18 (1,800). The 2010 guidelines were withdrawn in 2023. Country and product concentration are descriptive measures; they are not firm-level antitrust market assessments.
Within an HS6 code, dispersion of export unit values (USD per ton or per unit) across exporters is treated as a proxy for vertical differentiation: high unit-value = quality end of the ladder. The quality residual from Khandelwal (2010) orthogonalizes unit values against a demand index to back out unobserved quality. Primary references: Schott (2004) QJE; Khandelwal (2010) RESTUD. Appears on: quality, product.
Xij = G · (Yi Yj / Yw) · (tij / (Πi Pj))1−σ. Bilateral trade is proportional to the product of economic masses and inversely proportional to bilateral trade costs, deflated by the outward (Πi) and inward (Pj) multilateral resistance terms. Primary references: Tinbergen (1962); Anderson & van Wincoop (2003) AER. Practitioner guide: Head & Mayer (2014). Appears on: gravity, trade-costs, bilateral.
Poisson Pseudo-Maximum Likelihood estimator for gravity. Handles log-of-zero trade flows naturally (does not drop zero observations), is consistent under heteroskedasticity of the multiplicative residual, and gives elasticities directly on the constant-elasticity gravity equation. Primary reference: Santos Silva & Tenreyro (2006) RES. Appears on: gravity, trade-costs, tariff elasticity.
τij = (Xii Xjj / (Xij Xji))1/(2(σ−1)) − 1. Ad-valorem trade-cost equivalent backed out of observed bilateral and domestic trade, under the Anderson-van Wincoop structure. Primary reference: Novy (2013) EI; ESCAP implementation: Arvis et al. (2016). Appears on: trade-costs, bilateral corridor decompositions.
FKcc′ = Σp min(scp, sc′p) where scp is country c's share of exports in product p. Range [0, 1]. Measures competitive overlap of two export baskets. Primary reference: Finger & Kreinin (1979) EJ. Appears on: rankings (competitor overlap), country.
Cross-country regression of investment-to-GDP on saving-to-GDP: a coefficient close to one is read as a low degree of international capital mobility. Primary reference: Feldstein & Horioka (1980) EJ. Appears on: macro.
Maps SITC/HS products into five technology tiers: primary products, resource-based manufactures, low-, medium-, and high-technology manufactures. Primary reference: Lall (2000) Oxford Development Studies. Appears on: structural-change.
PRODYp = Σc (RCAcp / Σc′ RCAc′p) · GDPpcc;EXPYc = Σp scp · PRODYp. What the country exports looks like what rich countries export when EXPY is high. Primary reference: Hausmann, Hwang & Rodrik (2007) JEG. Appears on: structural-change, rankings.
Concentration-then-diversification U-shape in sectoral value-added shares across development levels. Primary reference: Imbs & Wacziarg (2003) AER. Appears on: structural-change, country composition discussion.
Ui = 1 + Σj (dij Yj / Yi) Uj, where dij is the dollar of industry i's output used by industry j per dollar of j's output and Yis gross output. Measures the average number of production stages between an industry and final demand; higher U = further upstream. Closed form follows the Leontief iteration on the inter-industry use matrix. Primary references: Antràs, Chor, Fally & Hillberry (2012) AER P&P; Antràs & Chor (2013) Econometrica. Appears on: gvc, supply-chain, structural-change.
Exposure-weighted difference-in-differences identifying local-labor-market effects of a trade shock using commuting-zone variation in import exposure. Primary reference: Autor, Dorn & Hanson (2013) AER. Appears on: structural-change narrative.
Event-study specifications around tariff announcements, with product-level import values and unit values as outcomes. Primary references: Amiti, Redding & Weinstein (2019) JEP; Fajgelbaum, Goldberg, Kennedy & Khandelwal (2020) QJE. Appears on: tariffs, quality, supply-chain narratives.
010121). Never cast to integer, leading zeros matter.All figures on this site are produced by server-side DuckDB queries over ZSTD-compressed Parquet files in data/parquet/. Total footprint: 1.4 GBParquet versus 20 GB SQLite, a 16× reduction on the BACI tables alone. Each figure exposes the SQL that produced it via a <details>element below the chart.
Partitioned tables are shaped as {table}/year={YYYY}/*.parquet so that year-filtered queries prune the partitions rather than scanning the full panel. Partitioned tables: country_year_product, country_year_product_ext, bilateral_year, unit_values, rca_matrix, product_proximity, pref_tariff_hs6, gravity_bilateral. All other tables are single-file Parquet.
Query pattern:
SELECT CAST(year AS INTEGER) AS year,
SUM(export_value) * 1000 AS value_usd
FROM read_parquet('data/parquet/country_year_product/**/*.parquet')
WHERE country_code = $1
GROUP BY year
ORDER BY year;Cross-year aggregations finish under 100 ms on a laptop with the Parquet files cached. The workbench runs as a Next.js 16 server component tree: no client-side data fetching, no REST hops, no ORM. DuckDB is called in-process via the @/lib/duckdb helper; results are typed through TypeScript interfaces and passed straight into SVG chart components.
Parquet files are regenerated from upstream releases by scripts in data/scripts/. The regeneration commit hash is carried in the file metadata where the upstream source supports it, and the upstream release date is recorded in data/parquet/MANIFEST.md.
Three DuckDB query patterns recur across the workbench. Documenting them here keeps the per-figure SQL short and avoids re-explaining the same idioms on every page.
Window functions for shares and rankings. World-share and within-year-rank calculations use SUM(...) OVER (PARTITION BY year) rather than a self-joined tot subquery. One pass over the partitioned parquet, no join fan-out, and the share column is computed next to the raw value. This is the pattern behind the HHI on the world page and the RCA numerator on country pages:
SELECT year,
country_code,
total_exports,
total_exports / SUM(total_exports) OVER (PARTITION BY year) AS world_share,
ROW_NUMBER() OVER (PARTITION BY year ORDER BY total_exports DESC) AS rank
FROM read_parquet('data/parquet/country_year_totals.parquet');Self-joins for t−1 lags and growth. Year-on-year growth, export-survival durations, and any lagged regressor on annual panels use a self-join on (iso3, year − 1) against the same table. DuckDB exploits the Parquet min/max statistics to prune partitions on both sides of the join. Window functions (LAG(x) OVER (PARTITION BY iso3 ORDER BY year)) are equivalent and sometimes preferable when the panel is strictly balanced; we use self-joins when the panel has gaps or when the analyst needs two rows side by side:
SELECT t.iso3,
t.year,
t.exports AS x_t,
tm1.exports AS x_tm1,
(t.exports - tm1.exports) / NULLIF(tm1.exports, 0) AS g
FROM totals t
LEFT JOIN totals tm1
ON tm1.iso3 = t.iso3
AND tm1.year = t.year - 1;GROUP BY iso3 deduplication before joining. The countries.parquet dimension has duplicate ISO3 rows for territories whose UN M.49 numeric code changed across BACI vintages (Belgium-Luxembourg, East/West Germany, Sudan / South Sudan). A naive join on code = country_code fans out those countries by the number of historical codes. Every country-level aggregate on the site aggregates first to iso3, then joins:
SELECT c.iso3,
COALESCE(ANY_VALUE(c.name) FILTER (WHERE c.name NOT LIKE '%(...%'), MIN(c.name)) AS name,
SUM(t.total_exports) * 1000 AS exports_usd
FROM read_parquet('data/parquet/country_year_totals.parquet') t
JOIN read_parquet('data/parquet/countries.parquet') c
ON c.code = t.country_code
WHERE t.year = 2024 AND UPPER(c.iso3) = c.iso3
GROUP BY c.iso3
ORDER BY exports_usd DESC;Three other conventions worth naming: ISO3 is upper-cased before the join, not after (keeps the comparison on the indexed key); HS6 is carried as VARCHAR(6)to preserve leading zeros; and any figure that shows BACI or FAOSTAT values multiplies by 1,000 at the SELECT level so downstream TypeScript sees USD, not thousands of USD. The unit is asserted in the SQL, not in the chart.
Chart types used across the workbench, with the decision rule for each. Every chart is server-rendered SVG from src/x/components/charts.tsx; there is no client chart library on analytical pages. When in doubt, prefer the type whose shape directly encodes the claim being made.
public/data/world-110m.json. Suitable for level variables (exports, tariff averages) and for changes (growth, share-shift). Not for variables with high within-country variance (use sub-national panels instead when available). Appears on: world, rankings, tariffs, supply-chain.Five limitations shape everything on the workbench and are worth naming plainly before the longer catalogue below. They are the places where 'read the SQL' is not enough: the data vintage or the reconciliation logic itself is the binding constraint, and the reader has to carry the caveat in their head for the number to mean what it looks like it means.
/monitor) and the monthly page (/monthly) are the right entry points; anything on the analytical pages is reconciled annual data.countries.parquet dimension has duplicate iso3 rows for some of these; always GROUP BY iso3 before joining to avoid double-counting./tariff-lab are drawn from Broda & Weinstein (2006) and Caliendo & Parro (2015). They are industry averages, not event-specific. Do not read them as structural estimates of any particular shock.References cited across the workbench, alphabetically by first author. Volume and issue given where the publication carries them.
If this workbench is useful in a paper, policy brief, or report, cite:
Hossen, M. D. (2026). TradeWeave Workbench. tradeweave.org/x. Data: CEPII BACI 202601 (retrieved 2026-06-01) release.