Official TypeScript/JavaScript SDK for BPS (Badan Pusat Statistik) WebAPI — Seamlessly access Indonesia's Central Bureau of Statistics data through a comprehensive, type-safe client library.
The STADATA JS SDK provides TypeScript/JavaScript developers with streamlined access to Indonesia's statistical data through the official BPS WebAPI. Create data-driven applications featuring demographic, economic, and socio-economic information from Indonesia's most authoritative statistical source.
- Functional Composable API —
initStadata()+use*()composables by default, with optional explicit clients for advanced use cases - Full TypeScript Support — Complete type definitions with IntelliSense support
- Result Pattern — Uses
neverthrowfor elegant, type-safe error handling - Tree-shakeable — Only bundle what you use
- Pagination Support — Built-in pagination handling for all list endpoints
- Request Cancellation — Cancel ongoing requests to optimize performance
- Immutable Entities — Predictable, safe domain entities
- Node.js >= 16.0.0
- Valid API key from BPS WebAPI platform
# npm
npm install stadata-js
# pnpm
pnpm add stadata-js
# yarn
yarn add stadata-jsimport { initStadata, usePublications, useDomains, DataLanguage, DomainType } from 'stadata-js'
// 1. Initialize once at app entry point
initStadata({ apiKey: 'your-api-key-here' })
// 2. Use composables anywhere — no client reference needed
const { fetchPublicationList, fetchPublicationDetail } = usePublications()
const { fetchDomainList } = useDomains()
// 3. Fetch data
const result = await fetchPublicationList({
domain: '7200',
lang: DataLanguage.ID,
page: 1,
perPage: 10,
})
result.match(
({ data, pagination }) => {
console.log(`Total: ${pagination.total}`)
data.forEach(pub => console.log(pub.title))
},
(error) => console.error('Error:', error.message)
)Full documentation: ipds-59.github.io/stadata_js
| Composable | Functions |
|---|---|
useDomains() |
fetchDomainList |
usePublications() |
fetchPublicationList, fetchPublicationDetail |
usePressReleases() |
fetchPressReleaseList, fetchPressReleaseDetail |
useStaticTables() |
fetchStaticTableList, fetchStaticTableDetail |
useDynamicTables() |
fetchDynamicTableList |
useInfographics() |
fetchInfographicList |
useNews() |
fetchNewsList, fetchNewsDetail |
useNewsCategories() |
fetchNewsCategoryList |
useVariables() |
fetchVariableList, fetchVariableDetail |
useVerticalVariables() |
fetchVerticalVariableList |
useDerivedVariables() |
fetchDerivedVariableList |
useSubjects() |
fetchSubjectList, fetchSubjectDetail |
useSubjectCategories() |
fetchSubjectCategoryList |
useUnits() |
fetchUnitList, fetchUnitDetail |
usePeriods() |
fetchPeriodList |
useDerivedPeriods() |
fetchDerivedPeriodList |
useStrategicIndicators() |
fetchStrategicIndicatorList, fetchStrategicIndicatorDetail |
useStatisticClassifications() |
fetchStatisticClassificationList, fetchStatisticClassificationDetail |
useCensus() |
fetchCensusList |
useTrade() |
fetchTradeData |
All functions return Result<T, ApiFailure> from neverthrow:
const result = await fetchPublicationList({ domain: '7200', lang: DataLanguage.ID })
// Option 1: match
result.match(
({ data, pagination }) => console.log(data),
(error) => console.error(error.message)
)
// Option 2: guard check
if (result.isOk()) {
const { data, pagination } = result.value
}
if (result.isErr()) {
console.error(result.error.message)
}const stadata = createStadataClient({
apiKey: 'your-api-key', // required
timeout: 15000, // optional, ms (default: 30000)
debug: true, // optional, enable debug logging
baseURL: 'https://...', // optional, custom base URL
})Version 2 introduces a breaking change from the class-based API to the composable API.
await StadataJS.init({ apiKey: 'key' })
const stadata = StadataJS.instance
const publications = await stadata.list.publications({
domain: '7200',
lang: DataLanguage.ID,
})import { initStadata, usePublications, DataLanguage } from 'stadata-js'
// initialize once at app entry point
initStadata({ apiKey: 'key' })
// use composables anywhere in your app
const { fetchPublicationList, fetchPublicationDetail } = usePublications()
const publications = await fetchPublicationList({
domain: '7200',
lang: DataLanguage.ID,
})StadataJS.init()→initStadata()StadataJS.instance.list.publications()→usePublications().fetchPublicationList()StadataJS.instance.view.publication()→usePublications().fetchPublicationDetail()- list/view methods are now grouped by composable (
useDomains,useNews,useDynamicTables, etc.) - global initialization is the default pattern, so you no longer need to carry a singleton instance around your app
If you need multiple clients (for example different API keys), you can still use an explicit client:
import { createStadataClient, usePublications } from 'stadata-js'
const client = createStadataClient({ apiKey: 'other-key' })
const { fetchPublicationList } = usePublications(client)
StadataJSclass is kept as@deprecatedin v2 for transition purposes and will be removed in v3.
If you need multiple clients (e.g. different API keys), use createStadataClient directly:
import { createStadataClient, usePublications } from 'stadata-js'
const client = createStadataClient({ apiKey: 'other-key' })
const { fetchPublicationList } = usePublications(client) // explicit clientMIT © IPDS-59