If you are moving from Bear to Notion, you need a reliable way to transfer your notes without losing the tags you carefully organized. Bear stores tags inline within the note body using the #tag format, but Notion does not recognize this format natively. This article explains how to build a repeatable import pipeline that converts Bear’s inline tags into Notion database tags. You will learn the exact steps to export from Bear, transform the markup, and import into a structured Notion database.
Key Takeaways: Bear-to-Notion Tag Conversion Pipeline
- Bear > Preferences > Export > Bear Backup (.bearbackup): Exports all notes with tags embedded in the text body.
- Python script with regex (re.sub and re.findall): Extracts #tag patterns and reformats them into Notion-compatible comma-separated tags.
- Notion API or CSV import with a Tags column: Inserts the transformed data into a Notion database where each tag becomes a Select property.
What Makes Bear Tags Different From Notion Tags
Bear stores tags as inline text using the #hashtag syntax. For example, a note might contain “Meeting notes #work #project-alpha”. Notion, on the other hand, uses a separate Select or Multi-Select property within a database row. Notion does not interpret inline #tag syntax. If you paste a Bear note directly into Notion, the #tags remain as plain text and are not recognized as structured data. To preserve tags as filterable metadata, you must extract each tag from the note body and place it into a dedicated Tags column during import.
Prerequisites for Building the Import Pipeline
Before you begin, make sure you have the following tools and access:
- Bear app (macOS): You need Bear installed to export your notes in the correct format.
- Python 3.7 or later: The script in this guide uses Python with the built-in
json,re, andcsvmodules. No third-party libraries are required. - Notion account with database creation rights: You need the ability to create a new database or modify an existing one.
- Notion API integration (optional but recommended): If you plan to automate the import, create a Notion integration at https://www.notion.so/my-integrations and copy the Internal Integration Secret token.
Step-by-Step Pipeline: Export, Transform, and Import
Step 1: Export Notes From Bear With Tags Intact
- Open Bear and select all notes
Click any note in the sidebar, then press Cmd+A to select all notes. Alternatively, choose a specific tag or folder if you only want to move a subset. - Export as Bear Backup
Go to File > Export Notes > Bear Backup (.bearbackup). This format preserves the full note body including inline #tags, creation dates, and modification dates. Save the file to your desktop asbear_export.bearbackup. - Extract the JSON from the backup
Bear Backup files are actually ZIP archives. Rename the file extension from.bearbackupto.zipand double-click to extract. Inside you will find a folder containing adatabase.sqlitefile and anotes.jsonfile. Copynotes.jsonto a working directory.
Step 2: Transform Bear Tags Into Notion-Compatible Format
- Create a Python script in your working directory
Open a text editor and paste the following code. Save it asbear_to_notion.py.import json import re import csv with open('notes.json', 'r', encoding='utf-8') as f: notes = json.load(f) output = [] for note in notes: title = note.get('title', '') body = note.get('text', '') # Extract all #tags (word characters only, no spaces) tags = re.findall(r'#([a-zA-Z0-9_-]+)', body) # Remove duplicates while preserving order seen = set() unique_tags = [] for t in tags: if t not in seen: seen.add(t) unique_tags.append(t) # Remove #tag from body to avoid duplication in Notion cleaned_body = re.sub(r'#[a-zA-Z0-9_-]+', '', body) # Strip extra whitespace cleaned_body = re.sub(r'\s+', ' ', cleaned_body).strip() output.append({ 'Title': title, 'Body': cleaned_body, 'Tags': ', '.join(unique_tags) }) # Write to CSV with open('notion_import.csv', 'w', newline='', encoding='utf-8') as f: writer = csv.DictWriter(f, fieldnames=['Title', 'Body', 'Tags']) writer.writeheader() writer.writerows(output) print(f'Converted {len(output)} notes. Output file: notion_import.csv') - Run the script
Open Terminal, navigate to your working directory, and runpython3 bear_to_notion.py. The script creates a file namednotion_import.csvwith three columns: Title, Body, and Tags. Each tag is separated by a comma and a space.
Step 3: Import the CSV Into a Notion Database
- Create a new Notion database
In Notion, click + New Page in the sidebar. Type/tableand select Table – Inline. This creates a database with default properties. - Add a Tags column with Multi-Select type
Click the + button in the table header. Name the columnTagsand choose Multi-Select as the property type. You do not need to predefine any options; Notion will create them automatically during import. - Import the CSV
Click the three-dot menu at the top right of the database, then select Import. Choose CSV and select yournotion_import.csvfile. In the mapping dialog, map the Title column to the Name property, Body to a Text property (create one if needed), and Tags to the Tags (Multi-Select) property. Click Import. - Verify tag preservation
After import, open any note. The Tags column should display each tag as a colored pill. If a tag was not created, check that the CSV column header exactly matches the property name (case-sensitive).
If the Import Does Not Preserve Tags Correctly
Tags Appear as Plain Text in the Body Instead of the Tags Column
This happens when the CSV import mapping does not assign the Tags column to the Multi-Select property. During the import dialog, verify that the Tags column from the CSV is mapped to the Tags (Multi-Select) property in Notion. If you mapped it to a Text property, delete the imported rows, adjust the mapping, and re-import.
Tags With Special Characters Are Not Recognized
Bear allows tags containing hyphens and underscores, but Notion Multi-Select options cannot contain commas. The Python script uses re.findall(r'#([a-zA-Z0-9_-]+)') to extract tags. If your tags include characters like . or # within the tag name, modify the regex pattern to include those characters. For example, change the pattern to r'#([a-zA-Z0-9_-.]+)'.
Duplicate Tags Are Created for Different Capitalization
Notion treats Work and work as separate Multi-Select options. To avoid duplicates, modify the Python script to convert all tags to lowercase before deduplication. Replace the line if t not in seen: with if t.lower() not in seen: and store the lowercase version in the CSV.
Bear Export vs Notion Import: Key Differences
| Item | Bear | Notion |
|---|---|---|
| Tag storage | Inline #tag within note body | Separate Multi-Select property in database |
| Export format | Bear Backup (.bearbackup) containing notes.json | CSV import with Title, Body, Tags columns |
| Tag delimiter | Space before # and space after tag | Comma-separated values in a single cell |
| Tag case sensitivity | Case-insensitive display | Case-sensitive options (duplicates possible) |
The pipeline above converts Bear’s inline tags into a Notion database-friendly format. After the import, use Notion’s database filters and views to sort notes by tag. For future imports, consider automating the process with the Notion API: create a new page for each note using the POST /pages endpoint and set the Tags property as an array of Multi-Select option names. This approach avoids CSV mapping issues entirely.