👤CSV→VCF

VCF to JSON Converter — From a vCard File to a Clean Contact Array

Phones, iCloud and Google Contacts export an address book as a .vcf because that is the format they speak. A script, a CRM API or a static site wants a JSON array — one object per person, keys a program can index without parsing N and TEL. Drop the vCard here and you get that array in the browser: names, phones and emails as camelCase strings, nothing uploaded. Toggle CSV or Excel if you would rather work in a spreadsheet; JSON is the shape for code.

👤
Written by Casey Marlin · Last updated
This update: JSON output covered by scripts/test-vcfjson.mjs; same parser as VCF to CSV
A vCard 2.1 quoted-printable block mapped to a JSON object with camelCase keys firstName, lastName, fullName, phone1, phone1Type, phone2, phone2Type, email1, email2 and company; missing fields stay as empty strings

Drop your VCF / vCard file here

.vcf with any number of contacts — vCard 2.1, 3.0 and 4.0 all supported, processed on your device.

The JSON shape

The download is a JSON array — one object per BEGIN:VCARDblock — whose keys are the camelCase form of the same 18 CSV headers. "First Name" becomes firstName, "Phone 1 Type" becomes phone1Type, "ZIP" becomes zip, "Job Title" becomes jobTitle. Every value is a string. A missing field is still present as "", so a script can read contact.email1 without checking whether the key exists.

Here is the exact output of two cards run through rowsToJsonText — the same function the download button calls. The first is a vCard 2.1 with a quoted-printable accented name and two telephone numbers; the second is a vCard 3.0 with a home address.

[
  {
    "firstName": "María",
    "lastName": "García",
    "fullName": "María García",
    "phone1": "+34 612 345 678",
    "phone1Type": "cell",
    "phone2": "+34 91 123 4567",
    "phone2Type": "work",
    "email1": "maria@example.com",
    "email2": "",
    "company": "Acme, Inc.",
    "jobTitle": "",
    "street": "",
    "city": "",
    "state": "",
    "zip": "",
    "country": "",
    "website": "",
    "notes": ""
  },
  {
    "firstName": "James",
    "lastName": "O'Brien",
    "fullName": "James O'Brien",
    "phone1": "+1 (555) 010-4477",
    "phone1Type": "work",
    "phone2": "",
    "phone2Type": "",
    "email1": "jobrien@example.com",
    "email2": "",
    "company": "Northwind",
    "jobTitle": "Engineer",
    "street": "88 Pine St",
    "city": "Seattle",
    "state": "WA",
    "zip": "98101",
    "country": "USA",
    "website": "",
    "notes": ""
  }
]

Pretty-printed with two-space indent. Empty strings stay visible: María has no job title or street, James has no second phone, and both objects still list every key.

Multiple phones and emails

A vCard can carry any number of TEL and EMAIL lines. Flattening them into an object has to stop somewhere. The converter keeps the first two of each, with the same numbering the CSV uses: phone1, phone1Type, phone2, phone2Type, email1, email2. There is no email type key. A third number or address is not given its own key — keep the original .vcf if you need every extra TEL or EMAIL line.

Type values are lowercase: cell, work, home or other. CELL and MOBILE both become cell; TYPE=WORK becomes work; HOME becomes home; a bare TEL with no TYPE is other. vCard 4.0 tel: URIs are stripped to the plain number before they land in phone1 or phone2.

In the sample, María's cell is phone1 and her work line is phone2; James has only a work number, so phone2 and phone2Type are empty strings, not omitted keys.

What is not exported

The JSON is a table in disguise, not a lossless vCard dump. PHOTO, LOGO and SOUND are binary properties. The shared parser, parseVcf, never copies them onto the contact object — they fall through the default case and disappear. A JSON array is the wrong place for a JPEG per row. Names, phones, emails, company, title, address, website and notes are what land in the file.

Custom X- fields are dropped the same way, with one internal exception: Apple's itemN.X-ABLabel is read only to set a phone or address type, then discarded. You will not see an xCustom key. Birthday and middle name are parsed in memory but are not among the 18 CSV columns, so they do not appear in the JSON either.

What does survive is the messy encoding. vCard 2.1 quoted-printable — Mar=C3=ADa, folded lines ending in = — is decoded as UTF-8, so María comes out as María. A CHARSET=ISO-8859-1 vCard from a very old handset can still show wrong; re-save it as UTF-8 first. Version 3.0 folded lines and grouped properties such as item1.TEL are unfolded. The same decoder as VCF to CSV, with no setting to pick.

Where you'd use it

Three jobs keep showing up. The first is seeding a CRM via its API: POST each object, mapping firstName / lastName / email1 / phone1 onto the vendor's fields. CamelCase keys are what most REST bodies already expect, so you rename one or two fields rather than parsing N and TEL out of a vCard.

The second is de-duplicating in a script. JSON.parse the file, group by email1 or phone1, and drop or merge repeats before anything goes back onto a phone. Empty firstName or empty phone1 also surfaces half-filled cards. Phone values stay strings, so a filter on numbers starting with + still works.

The third is feeding a static site: a team page, a directory, mailto: links at build time. Drop the .json next to the code and map. Nothing is uploaded, so you can convert a private address book offline and commit only the fields you want public. For a mail merge, toggle to CSV or Excel — those paths share this parser.

Going back

JSON is the working copy; phones still want a .vcf. After you have filtered, de-duplicated or filled the blanks, drop the array on the JSON to VCF converter. It accepts a top-level array of objects — the exact shape this page writes — and maps firstName, lastName, phone and email through the same header rules as CSV. A round-trip will not restore PHOTO or custom X- fields that were never exported; keep the original vCard as the archive until one test contact comes back clean.

Pick vCard 3.0 unless a device is genuinely old. Android, iPhone and Google Contacts all import 3.0; 2.1 is for feature phones; 4.0 is for apps that ask for it. If the cleaned list is already a spreadsheet, use CSV to VCF or Excel to VCF — the same engine from a table.

VCF to JSON — FAQ

  • Is my VCF file uploaded anywhere?

    No. The converter is JavaScript that runs in your browser tab. The .vcf is read locally, parsed into the same rows as VCF to CSV, and written to a .json on your device — there is no upload endpoint. You can disconnect from the network after the page loads and still convert.

  • What are the JSON key names?

    They are the camelCase form of the 18 CSV column headers: firstName, lastName, fullName, phone1, phone1Type, phone2, phone2Type, email1, email2, company, jobTitle, street, city, state, zip, country, website, notes. "First Name" becomes firstName, "Phone 1 Type" becomes phone1Type, "ZIP" becomes zip. Every value is a string; a missing field is still present as an empty string, so every object has the same keys.

  • What happens if a contact has several phones or emails?

    The first two telephone numbers land in phone1 / phone1Type and phone2 / phone2Type; the first two email addresses land in email1 and email2. Type values are lowercase cell, work, home or other. There is no email type key. A third number or address is not given its own key — flattening a vCard into a table has to stop somewhere. Keep the original .vcf if you need every extra TEL or EMAIL line.

  • Are contact photos included in the JSON?

    No. PHOTO (and other binary properties such as LOGO or SOUND) stay in the vCard and are not written into the array. Custom X- fields are dropped the same way. The parser never copies those properties onto the contact object, so they cannot appear as keys. Names, phones, emails, company, title, address, website and notes are what land in the JSON.

  • Does it read vCard 2.1 and 4.0, or only 3.0?

    All three. vCard 2.1 quoted-printable (including soft line breaks) is decoded as UTF-8, so María comes out as María instead of Mar=C3=ADa. Version 3.0 is the common case — escaped commas, folded lines, iCloud grouped properties such as item1.TEL. Version 4.0 tel: URIs are stripped to the plain number before they go into phone1 or phone2. Mixed-version files parse card by card.

  • How many contacts can I convert at once?

    Every BEGIN:VCARD…END:VCARD block in the file becomes one object in the array. The preview table shows the first 8; the download contains all of them. Hundreds or a few thousand contacts are fine in a modern browser. The limit is the memory of the tab, not a server quota — split a huge dump only if the tab starts to struggle.

  • Can I get CSV or Excel instead of JSON?

    Yes. Use the CSV / Excel (.xlsx) / JSON toggle above the download button, or open the dedicated VCF to CSV and VCF to Excel converters. All three formats share the same parser and the same 18 fields; JSON is the camelCase array, CSV is the spreadsheet with a UTF-8 BOM, and .xlsx locks phone columns as text.

Parser follows RFC 2426, RFC 6350 and the vCard 2.1 spec. JSON keys are camelCase of the CSV columns; empty fields are empty strings. Last checked: August 26, 2026. About this site