100% local — your data never leaves your browser

JSON to Mongoose — A Model File to Require

Turn a JSON sample into a Mongoose schema. One schema per object, required where the sample shows a value, ready to export as a model.

Instant Private Zero cookies

JSON input

Mongoose output

What this tool does

A JSON sample becomes a Mongoose schema, one const per object, and a model at the end.

{ "id": 1, "name": "Ada", "address": { "city": "Paris" } }
import mongoose from 'mongoose';

const AddressSchema = new mongoose.Schema({
  city: { type: String, required: true },
});

const RootSchema = new mongoose.Schema({
  id: { type: Number, required: true },
  name: { type: String, required: true },
  address: { type: AddressSchema, required: true },
});

export default mongoose.model('Root', RootSchema);

Children first: schemas are runtime values, so one has to exist before another uses it. An array of documents at the root describes its first element — that is the shape of the record, and the list is what the collection already is.

required on an array needs help

Mongoose gives every array a default of []. A field declared { type: [String], required: true } therefore validates even when the key is absent: the default satisfies the requirement. Checked on Mongoose 9:

documentrequired: truerequired: true, default: undefined
{ tags: ["a"] }passespasses
{ tags: [] }passespasses
{}passesfails

The first column is not what the word says. Array fields are therefore emitted with default: undefined alongside required: true, so a missing array is the error it claims to be. An empty array still passes, which is right: it is a value.

Nested objects become subdocuments, with their own _id

address above is a subdocument, and Mongoose gives it an _id of its own:

{ _id: ObjectId("…"), address: { city: "Paris", _id: ObjectId("…") } }

That is Mongoose’s default, not something added here. If those inner identifiers are noise for you, new mongoose.Schema({ … }, { _id: false }) removes them — a decision about your documents, which is why it is left to you.

A MongoDB export is not the JSON you want

mongoexport writes extended JSON:

{ "_id": { "$oid": "65f1c…" }, "created": { "$date": "2026-01-01T00:00:00Z" } }

Those are objects, so the generator makes subdocument schemas of them — _id ends up as a subdocument that carries its own _id, which is certainly not what you meant. Replace them with mongoose.Schema.Types.ObjectId and Date by hand. A key named $oid means something to MongoDB and nothing to a structural reader.

Mixed is where the sample went quiet

null, an unknown value, an empty array and a heterogeneous array all give mongoose.Schema.Types.Mixed. A Mixed field is not validated and, worth knowing, changes to it are not tracked automatically — you have to call markModified. Narrow it as soon as you know what belongs there.

Private by design

Everything runs locally in your browser with JavaScript. Your data is never uploaded, which makes the tool safe for sensitive content, and it keeps working offline.

Frequently asked questions

Why do array fields carry `default: undefined`?
Because without it, `required: true` on an array does nothing. Mongoose gives every array a default of `[]`, so a document with the key missing still validates — the requirement is satisfied by the default. Adding `default: undefined` makes the field behave the way the word "required" reads. It was checked against Mongoose 9, not assumed.
My nested object gained an `_id`. Where does that come from?
From Mongoose: a nested schema used as a field type is a subdocument, and subdocuments get their own `_id` by default. If you do not want one, pass `{ _id: false }` as the schema options. It is left in because it is Mongoose\u2019s default and removing it silently would change what your documents look like.
I pasted a MongoDB export and got `$oid` fields. Is that right?
It is what the sample contained. A `mongoexport` document writes extended JSON — `{"_id": {"$oid": "…"}}`, `{"$date": "…"}` — so the generator sees objects and makes subdocuments of them. Replace those with `mongoose.Schema.Types.ObjectId` and `Date`: the tool cannot know the convention behind a key it has never seen.

Related converters