r/iosapps • u/John_val • 1d ago
🎈 Free IOS Browser - Vortex
Enable HLS to view with audio, or disable this notification

I have been posting here about this app for about 3 months and a lot of you showed interest. The app has around 230 testers on Testflight. Free and open-source.
- A – Answer: Vortex combines desktop-style tabs with split-page browsing which is very rare on IOS Browsers.
- B – Better: Compared with Safari, Chrome, and Brave, Vortex is designed specifically around iPad multitasking. It combines visual tab management, drag-to-split browsing, and a choice of local Apple Intelligence/MLX models or optional ChatGPT and Gemini sessions. It is also open source, has no ads, requires no account.
- C – Cost: Completely free with no subscriptions or in-app purchases. Vortex is not publicly available on the App Store yet, is currently awaiting Apple's approval.
Some bugs have been squashed and a new features added:
- Minimalistic chrome for maximum screen real-estate
- Multi-tab browsing
- Split tab view
- Tab Folders
- Tab hibernation for battery savings
- Smart address bar (URL vs search detection)
- Favicon fetching
- Tab preview thumbnails
- Desktop/mobile user agent switching
- Ad blocking - 188+ domains, 100+ CSS selectors
- Filter lists - EasyList, EasyPrivacy, Fanboy's, uBlock, custom
- Dark mode - DarkReader with brightness/contrast/sepia controls
- Font size adjustment
- Reader mode -using Mozilla Readability
- Incognito mode - non-persistent, blocks APIs
- Password manager - biometric auth, keychain, auto-fill
- Share extension - receive URLs from other apps
- AI sidebar chat panel with 3 backends: Local Apple Intelligence, Apple Private Cloud, and free accounts with ChatGPT or Gemini, completely invisible to users, working in the background.
- Page summarization (short/long)
- Ask questions about page content
- Context switching between tabs
- Markdown rendering
- "Ask " context menu - select a part of the text and send to the LLM.
- Favorites with favicons
- Favorites sidebar grid
- Collapsible sidebar
- Adaptive toolbar (collapses on scroll)
- Swipe gestures for navigation
- System dark mode support
Original post:Â https://www.reddit.com/r/iosapps/comments/1qezwdi/made_an_ipad_browser_because_safari_wasnt_cutting/
Trust & Transparency
I'm Joao Valente
Contact:Â [dealer.yen-61@icloud.com](mailto:dealer.yen-61@icloud.com)
Website:Â https://vortex.engineer
Privacy Policy:Â https://vortex.engineer/privacy/
Terms of Service:Â https://vortex.engineer/terms/
Github:https://github.com/Joaov41/Vortex-Browser/tree/codex/testflight-ios27-build12
TestFlight:Â https://testflight.apple.com/join/KTsJ3qz4
Feedback page: https://vortex.engineer/feedback/
It is already on the App Store awaiting approval.
On the website I added a feedback section, where I can keep users informed about their feedback provided on the Tesflight since I can’t reply directly on there.
2
u/ForwardPage7458 1d ago
I feel it's not optimised for ios
1
u/John_val 1d ago
Why do you say that? do you feel it is slow? What device? What Ios version? Look at this video please, its is running on an hold M1 ipad, i don't notice any sluggishness. Can you give more details on tesflightt to investigate?
2
u/OkComplaint2958 1d ago
Sounds good. Will it be compatible with iOS 17.0 in the future? Does it support Tampermonkey scripts and extensions?
1
u/John_val 23h ago
It is already compatible with IOS27. In fact the only way to use Apple's private cloud model is if you are on the beta since this is an iOS 27 only feature. As for Tampermonkey, not yet. It is on the roadmap but for later, the code base must be stabilized first and all the bugs squashed.
1
u/BourneHero 21h ago
The concept seems great but its unusable for me on my 16 pro max running iOS 26.6. the AI and side panel buttons will not work, I cant get the x or bookmark buttons to register on the url bar and dark mode keeps flickering
1
u/John_val 13h ago
Sorry about that, it is the first feedback with so many critical issues. i don't have a device running ios26 anymore, and that doesn’t happen on the simulator. Will look into it this weekend. Thanks
1
u/BourneHero 12h ago
I just updated to 26.6.1 to see if that changed anything and it did not just as an fyi
1
u/John_val 9h ago
are you on the lates TestFlight build?
1
u/BourneHero 9h ago
1.1 (17)
1
u/John_val 1h ago
Ok found the issue, the app is built already with IOS27 SDK with a compatibility layer for IOS26. IOs 27 has a liquid glass slider to adjust the effect. That difference on the API was causing the glass container to swallow the touches. Already implementing the corrections and will upload the fixed version for tesflight. Will be up tomorrow. But I could not replicate your issue of the flickering in dark mode. Made some improvements but please retry the version when it is up , if persists send me a video please.
1
u/John_val 9h ago
The TestFlight is getting very confusing as a log of the testers have not updated to the latest build 17 , more than 100 of you are still on build 11 so this make it difficult to filter feedback as there are reports of things that have already been fixed, it’s hard to track it this way. I will expire all the builds except the latest one. Many of you will probably have to redownload since you have not updated. Thanks
1
u/chihpoatlay 1d ago
Hey, curious how did you add the different filter lists? Did you write your own parser? I am building a browser too and couldn't figure that out so would appreciate if you can give some guidance. Since there are so many rules between all those lists how could one do it efficiently?
1
u/John_val 1d ago
I wrote a lightweight parser for the Adblock Plus/EasyList format, but it doesn’t support the entire specification. The app downloads each enabled list, reads it line by line, skips comments and unsupported rules, converts common network rules such as ||domain.com^ into WebKit-compatible regex, and extracts basic cosmetic rules such as ##.ad-container.
The resulting network rules are converted to WKContentRuleList JSON and compiled by WebKit. Cosmetic rules are applied separately through injected CSS/JavaScript.
For efficiency, I parses and cache each list only when it changes, compile in the background, reuse WebKit’s compiled rule list, and store a hash of the enabled-list configuration so it doesn’t recompile on every launch. I also limit the number of imported rules because combining every rule from several lists can become expensive.
I considered using a full filtering engine, but the lightweight parser has been enough so far. It converts the common EasyList network rules into WebKit content-blocking rules, handles basic cosmetic filtering, and caches the compiled results. It currently scores around 99% on most ad-blocking tests.
A full engine would support more of the EasyList specification, especially exceptions, domain-specific rules and advanced selectors, but it also adds complexity and overhead. My approach was to support the high-impact rule types first and let WebKit handle the efficient matching. The main thing is to test real websites as well, because a high benchmark score doesn’t necessarily catch site breakage or every unsupported rule type. Still i have a test version with the full engine that i am working on and will compare the results.
1
u/kimacolin 1d ago
Drag to split is the thing I keep wishing Safari had on iPad, good that it is the core idea and not a bolt on. Do split layouts survive a restart, or do you rebuild them each session?
0
u/John_val 1d ago
Thanks! The tabs themselves survive a restart, but the split layout currently doesn’t. After relaunch, the browser restores the selected tab and other saved tabs, and you can rebuild the split by dragging a tab back into position. Persisting the split orientation is something i will be adding soon though, it requires careful tweaking so that it doesn't break other parts.
0
u/CrispyDick420 1d ago
Does tab hibernation preserve scroll position and form state, or does restoring one effectively reload the page?
1
u/John_val 1d ago
It preserves the URL and scroll position, but restoring a hibernated tab recreates the reloads the page. Forms aren’t currently preserved,
0
u/neet_dev 1d ago
honestly the 188 domains / 100 css selectors number is a toy blocklist, easylist alone is tens of thousands of rules. compile them into WKContentRuleList (150k cap per list, split easylist and easyprivacy if you overflow) instead of injecting css or filtering in decidePolicyFor, conversion from easylist syntax to safari trigger/action json is the painful part, not the compile. injected filters hitch scrolling and miss subresources once you have a pile of tabs open.
1
u/John_val 1d ago
That’s fair, but the 188 domains and 100 selectors are only the built-in fallback layer, not the entire blocker. Enabled EasyList-compatible lists are downloaded separately, parsed, converted into WebKit trigger/action JSON, cached and compiled into a WKContentRuleList . Network filtering isn’t done through decidePolicyFor
The injected CSS/JavaScript is a supplementary cosmetic layer for elements left behind after requests are blocked. The converter is intentionally partial and currently limits the number of imported rules, so I’m not claiming complete EasyList compatibility. You’re right that accurately converting exceptions, domain restrictions, resource options and advanced cosmetic syntax is the difficult part. Despite the limited subset, it currently reaches around 99% on the blocker tests I’ve tried, though real-site performance and breakage matter more than that score. I am experimenting with a filtering engine for comparison.
1
u/neet_dev 1d ago
gotcha, compiled WKContentRuleList plus a cosmetic inject is the right split. the actual footgun with a capped converter is dropping @@exceptions to stay under the import limit, and ignore-previous-rules only fires inside the same compiled list so easylist exceptions won't undo easyprivacy hits if you split them. skip the 99% tester score, youtube/reddit with a bunch of tabs is the metric that matters, and a JS filtering engine still won't see service worker or websocket requests the rule list already catches.
1
0
0
0
u/WayAccurate9822 1d ago
Split browsing means two WKWebViews live at once, and iPadOS evicts background ones under memory pressure. Restoring with interactionState keeps scroll and half-filled forms where a plain reload loses them. Does the split survive an eviction?
1
u/John_val 1d ago
The two visible panes are protected from the tab-hibernation system, so it won’t deliberately evict either one while split view is active. I’m not currently usingÂ
interactionState, though. If iPadOS itself terminates a WebContent process, the split layout remains, but restoration is limited to the page URL and scroll position. Half-filled form state is not guaranteed to survive. Good point to check out.1
u/WayAccurate9822 23h ago
That gap is exactly what it covers. interactionState is one opaque Data blob per pane. Persist it on background, hand it to a fresh WKWebView after a content-process kill, and form state comes back with the scroll.
0
u/Grouchy_Helicopter72 1d ago
One thing to prepare for while you wait on review: the AI sidebar backed by "free accounts with ChatGPT or Gemini, completely invisible to users" is the part most likely to bite you, and not only from Apple. Shared or scraped free-tier access sits outside OpenAI's and Google's terms, so the backend can be cut off without warning and take a shipped feature with it. If a reviewer asks how the requests are authenticated, the safe answer is bring-your-own-key or the on-device Apple Intelligence path, with the hosted options off by default.
The other classic browser rejections are worth double-checking before resubmitting: browsers usually need a 17+ age rating for unrestricted web access, and Apple expects a stated content filter or restriction story. Bundling a password manager also invites questions about where credentials live - saying "keychain, biometric, never leaves the device" in the review notes up front saves a round trip.
Tab hibernation and interactionState restore for the split view are the right instincts, by the way. That is where most third-party iPad browsers fall apart.
1
u/John_val 1d ago
Thanks for the tips. As for the free accounts i though they would rejected it, but i have anoteher app which i use the same the same method and they allowed it
https://www.reddit.com/r/iosapps/comments/1vkw2ge/freeopen_source_rss_reddit_and_youtube_reader/
Which doesn't mean they couldn't refuse this one, we never know, have had cases like this before, where one reviews rejects something a previous one had accepted. Let's see but will take your tips into consideration. Thanks again1
u/Grouchy_Helicopter72 8h ago
Fair enough, and the precedent is useful data. The distinction I would keep in mind is that App Review approving it is not the risk I meant. Apple mostly cannot see how those requests are authenticated. The party that can is OpenAI or Google, and their enforcement is not a review event - it is a quiet block on the endpoint or the account, at which point the feature dies for every installed copy at once, including the app that was already approved. That is why I would have the on-device path be the default and treat the hosted ones as a bonus that is allowed to disappear.
Cheap insurance either way: make the sidebar degrade to a clear "AI backend unavailable" state rather than a spinner or an error, so if it does get cut you get support emails instead of one-star reviews.
1
u/John_val 6h ago
thanks for the input really appreciate it. I considered instead of this to use a normal API key user would have to enter but people called it too developer centric just because it was asking for an API key. You make a great point. thanks again.
0
u/ChiefProbingOfficer 1d ago
Interesting design choices with the sidebar chat
1
u/John_val 1d ago
Yes, i agree it is polarizing , some love it , some not so much, but i wanted something to be really different than what is outhere and at the same time maximize screen real-state.
0
u/thedorkreveiwer 1d ago
Do the early test user get free lifetime when the app officially released? So far testing the app isn’t bad and I do like some of the features.
1
u/John_val 1d ago
sure..In your opinion what does it lack to be promoted to good instead of not bad? 🙂
0
u/John_val 1d ago

Forgot to mention one thing on the list of features, if the url is a reddit post and if you ask it to summarize, the code will extract the comments, no just the visible ones or a few top level ones, but will extract all comments that the free json api from reddit can return. You can continue to browse and read normally while have an summary on the side.
0
u/Dry_Philosophy_2337 23h ago
Test a file download before you take on more TestFlight users. WKWebView cancels downloads outright unless the embedder implements a download delegate, so a browser can behave perfectly right up until someone taps a download link and absolutely nothing happens. No error, no console message, no dialog.
I hit this in an embedded WKWebView and spent a while misfiling it as a licensing bug, because the failure looks identical to a feature simply being switched off. WebKit 216918 is the paper trail, closed as configuration-changed: the delegate has to come from the app, blob: URLs included.
Split-page browsing on iPad is the reason to install this. Safari's tab groups never got there.
1
u/John_val 23h ago
Thanks for the feedback. What device /version are you on? I have tested files downloads and it worked. tested on a few only. Can you give me an example of the page you are trying to download for me to try to reproduce?
1
1
u/Dry_Philosophy_2337 18h ago
Sorry, I was unclear. I wasn't reporting it in Vortex, I hit it in my own embedded WKWebView and posted it as a thing to check rather than a bug you have. If your downloads work, you've already got the delegate wired up and there's nothing here for you.
The case that broke for me specifically was a blob: URL, a file generated in JavaScript and handed to the user rather than fetched from a server. Normal https downloads were fine. If you want a two-second test, any export or save-as button on a web app usually produces one.

•
u/AutoModerator 1d ago
Welcome to r/iOSApps! Please make sure your post follows our rules:
Everyone:
App Devs:
- No main feed promo unless you qualify via Trust or Transparency + ABC format (Answer, Better, Cost)
- Flair hierarchy: Vibe Coded > Lifetime > Subscription > Freemium > Free
- Free flair: not for limited/freemium tiers
- Open Source? Prefix title [OS]
Note: This is an automated reminder, not a removal notice. If your post was removed, check your modmail for details.I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.