Data-lake browser
Browse and query object stores and HDFS from the browser — S3, MinIO, R2, B2, Wasabi, GCS, Azure Blob and WebHDFS/HttpFS: buckets and folders, uploads with resumable multipart, Range downloads, presigned URLs, Parquet/ORC/Avro schema and row-group statistics, DuckDB SQL over files, HDFS block locations, bucket CORS/policy/lifecycle generators, and the aws/mc/gcloud/az/hdfs command and curl for every action.
Added
How to use it
One workspace for the files of a data lake, wherever they sit: S3-compatible object stores,
Google Cloud Storage, Azure Blob Storage and HDFS. Pick a bucket, walk its folders, look inside a
Parquet file’s row groups without downloading it, run SQL over a few files, upload a 2 GB export in
resumable parts, and copy the exact aws s3, mc, gcloud storage, az storage or hdfs dfs
command for what you just did. It opens on a demo bucket that lives in the page (CSV, NDJSON,
JSON, Parquet, Avro, ORC and an image), so everything can be tried without an account.
How to use it
-
Connection — choose one, or + New and ✎ Edit:
-
S3 profile in the gitwebsite app (recommended). The gitwebsite app (or
gw serve) signs each request itself with a profile you add once —gw companion s3 add lab --endpoint http://192.168.1.20:9000 --region us-east-1 --path-styleandgw companion secret set s3:lab— so the keys stay in the macOS Keychain and the bucket needs no CORS. Press ⚡ Use the gitwebsite app and approve the code in the app. Through the app you can list, read (with Range), upload up to 100 MB per file, delete (confirmed in the app), copy (by reading and writing again) and presign; multipart, versions and bucket settings need a direct connection. -
S3-compatible, keys in this page — Amazon S3, MinIO, Cloudflare R2, Backblaze B2, Wasabi, GCS with HMAC keys, or any other S3 API. Requests are signed here with AWS Signature Version 4 (WebCrypto); the keys are kept in the page’s memory and gone when you close it, unless you tick Remember (stored unencrypted in this browser — a warning says so). The bucket must allow this page with CORS: Generators → CORS gives the exact rules for each provider, and Bucket → PutBucketCors applies them where you may.
-
Google Cloud Storage — the JSON API with an OAuth access token (
gcloud auth print-access-token), and a project id to list buckets or the bucket names. -
Azure Blob — a SAS URL for the account (lists containers) or one container; it needs
landr, andw,c,dto change things. CORS is set on the storage account. -
HDFS — the namenode’s WebHDFS (
http://namenode:9870) or HttpFS (:14000), directly (the cluster then needs the Hadoop cross-origin filter, shown under Generators → CORS → HDFS) or through the gitwebsite app (relay/lan: no CORS; the app asks you the first time the page reaches a new LAN host). Simple authentication (user.name=) or a delegation token. Datanode addresses rewrites the datanode names in WebHDFS’s redirects for clusters in Docker or Kubernetes (dn1:9864=10.0.0.21:9864).
-
-
Browse — the tree on the left lists buckets (containers, the HDFS root) and the folders you have opened; the list pages through ListObjectsV2 continuation tokens (Azure markers, GCS page tokens, WebHDFS
LISTSTATUS_BATCH) with Load more. Starts with… searches by key prefix on the server; Filter this page narrows what is listed; click a column to sort (folders first). Tick rows to delete several at once; + Folder creates a prefix; drop files on the browser or ⇪ Upload to upload into the open folder. -
Click a file. Info shows the size, ETag (and what a multipart ETag means), storage class, content type, user metadata, versions, and for HDFS the owner, permissions, replication, block size, the blocks along the file with their datanodes (
GETFILEBLOCKLOCATIONS), and a replication setter. Preview shows text, CSV (delimiter detected), JSON, NDJSON and images, read with a Range request (the first 256 KB) — gzip files are inflated when small. Schema reads only the footer of Parquet (FileMetaData: schema with logical types, every row group and column chunk with codec, encodings, compressed and uncompressed sizes, min/max statistics and null counts), the tail of ORC (types, stripes, column statistics; ZLIB and Snappy footers) and the header and first blocks of Avro (writer schema, codec, rows). Commands lists the CLI equivalents for the file and the last request as curl. -
Actions: Download (8 MB Range reads with progress; big S3 files through a presigned URL), Presigned URL with your choice of expiry (1 s – 7 days), Copy, Move / rename (S3 copy
delete; WebHDFSRENAME), Query in SQL, Delete (always confirmed). -
SQL — DuckDB-wasm in a worker. ▶ Query in SQL adds a file under its name; a query that names it fetches it (up to 200 MB) the first time. On a direct S3 connection, Parquet over 32 MB is read by Range through a presigned URL, so DuckDB fetches only the footer and the columns a query needs. Examples include
parquet_metadata(),parquet_schema()andSUMMARIZE. Export the result as CSV, JSON or Parquet. The demo’s files can be queried by name (SELECT * FROM 'cities.csv'). -
Bucket — the bucket’s location, versioning, CORS, policy and lifecycle (S3 direct, GCS), each with its CLI command; for HDFS the folder’s content summary and quotas.
-
Generators — bucket CORS for Amazon S3, MinIO (one server-wide setting), Cloudflare R2, Backblaze B2 (native rules with
s3_*operations), Wasabi, GCS, Azure and Hadoop, with the command that applies it; a least-privilege IAM policy (read-only, read-write or write-only, scoped to a prefix with ans3:prefixcondition on ListBucket); bucket policies (deny non-TLS, public read of a prefix, read for one role); lifecycle rules (transition, expiry, old versions, abort incomplete multipart uploads). -
Transfers — uploads and downloads with progress and speed. S3 files over 16 MB go up as multipart uploads (8 MiB parts, four at a time, raised so a file fits in 10,000 parts); Pause lets the running parts finish, Resume carries on, and an upload interrupted by a reload resumes when you choose the same file again (the upload id and part ETags are kept in this browser). Azure uploads over 16 MB use Put Block / Put Block List the same way.
-
Requests — every request the page made (signatures and tokens masked) and Copy as curl: SigV4 requests use
curl --aws-sigv4with$AWS_ACCESS_KEY_ID/$AWS_SECRET_ACCESS_KEY, the app’s requests$GW_COMPANION_TOKEN, Azure$AZURE_SAS_SIG— never the secret itself.
⛶ Full screen (or F) gives the browser the whole screen; ◫ Panels hides the connection panel.
Limits
-
Kerberos (SPNEGO) clusters are out of scope: a browser page cannot do the Kerberos handshake for WebHDFS. Use a delegation token from a Kerberized gateway, or HttpFS behind a proxy that authenticates.
-
ORC rows are not decoded (DuckDB-wasm has no ORC reader) — only the schema, stripes and statistics. Avro rows are decoded for the
null,deflateandsnappycodecs; Parquet’s and ORC’s ZSTD and LZ4 footers are fine (footers are not compressed in Parquet), ORC footers compressed with ZSTD/LZ4 are not read. -
GCS presigned URLs need a service-account private key, which the page does not take (the
gcloud storage sign-urlcommand is shown). GCS uploads are single requests. -
Through the gitwebsite app: uploads up to 100 MB, no multipart, versions or bucket settings (the app’s relay/s3 refuses them); WebHDFS writes and reads through the app need the datanodes reachable from the app’s computer too.
-
Direct mode is only as good as the store’s CORS: a hidden
ETagheader breaks multipart uploads, a missingRangein AllowedHeaders breaks previews and DuckDB’s Range reads. -
Folder deletes and renames work object by object (S3 DeleteObjects in batches of 1,000), so a large prefix takes a while; S3 copy is single-request (objects up to 5 GB).
-
Secrets you choose to remember are stored unencrypted in this browser’s localStorage.
Tested against the AWS SigV4 test suite and the S3 API reference’s signing examples (headers and presigned URLs), Parquet/ORC/Avro fixtures written by pyarrow 26, DuckDB 1.5 and fastavro 1.13, and live against MinIO and an Apache Hadoop 3 namenode, datanode and HttpFS — directly and through the gitwebsite app’s companion (relay/s3 and relay/lan).
Related: AWS architecture builder, Data wrangler (DuckDB recipes over local files), Postgres, Kafka client, Container dashboard, Storage engines.
Linking to an example
Share link copies the generator settings and the SQL editor’s query (never connections, keys,
tokens or SAS URLs). Put the tab after #: browse, sql, bucket, generate, transfers or
requests.
| Parameter | Meaning | Example |
|---|---|---|
|
a preset (below) |
|
|
the query in the SQL editor |
|
|
generator: |
|
|
CORS generator provider: |
|
|
allowed origins, space-separated |
|
|
bucket for the generators |
|
|
prefix for the IAM policy, bucket policy or lifecycle rule |
|
|
IAM policy access: |
|
|
a demo file to open ( |
|
Presets:
-
?example=demo— the demo bucket with a Parquet file’s row groups and statistics open. -
?example=demo-avro— an Avro file (snappy) decoded with its writer schema. -
?example=sql— a GROUP BY over the demo’scities.csvin DuckDB. -
?example=cors-r2,?example=cors-b2,?example=cors-minio— the CORS this page needs on R2, B2 and MinIO. -
?example=iam-readonly— a read-only IAM policy formy-lake/curated/. -
?example=lifecycle— logs to Glacier Instant Retrieval after 30 days, deleted after a year.
Feedback is a gift. Something to improve, a feature to add, or a bug? Tell me.
Runs entirely in your browser — network requests go only to the services named on this page.