Cute File Browser with jQuery and PHP

Cute File Browser with jQuery and PHP

Today we want to share a cool experiment with you. It is a cute file browser, which you can upload to a folder somewhere on your site and share documents, pictures and other files with the world. The app is built with PHP and jQuery and uses CSS3 extensively – no images or icons were used in the design, and the animations are smooth and work well even on smartphones.

How to use it on your site

Go ahead and grab the zip file from the download button above. Unzip it, then upload it to your server. The folder files is where you should place everything that you wish to share. No further set up necessary – the script doesn’t use a database and no configuration is needed.

Cute file browser

Cute file browser

The idea

If you wish to learn more about how it works, here is a high-level overview of the functionality:

  • A PHP script – scan.php – scans the files folder and returns all files and folders as a single JSON object.
  • Our JavaScript code, with the help of jQuery, takes this JSON, and turns it into a grid of files and folders. Clicking a folder re-renders the view with its contents.

Because there is only one request to the backend involved, browsing through the file list and searching is instantaneous. We also update the URL and use the hashchange event to monitor for navigation using the back/forward buttons.

We invite you to play with the code – it has lots of comments and is relatively easy to follow.

Forcing files to download

Browsers open text files instead of downloading them. If you wish to force all files to download, place this .htaccess file in the files folder:

<Files *.*>
ForceType application/octet-stream

It should be called .htaccess (with a leading dot). This file is only supported on Apache web servers.

The design

The PSD for the design is available for free to all of our newsletter subscribers! Join or login from here to download it.

We hope that you find our file manager useful! There are lots of cool things that can be added to it, like browsing photos in a lightbox, playing back audio and video, and even enhancing it with file management features and uploads. We’d love to see what you come up with!

Presenting Bootstrap Studio

a revolutionary tool that developers and designers use to create
beautiful interfaces using the Bootstrap Framework.

Learn more
Web Browser Frame DevKit Box Mouse Cursor
by Nick Anastasov

Nick is a JavaScript programmer who loves Node and all things HTML5. He is interested in photography and is the resident food expert at Tutorialzine's office.

1Share this post
2Read one more article
3Get your free book
Book Cover
jQuery Trickshots

Tutorialzine's advanced jQuery techniques book.



  1. NICO says:

    THAT is a beautiful piece of software again!
    Thank you so much for sharing. Great job!

    1. Pieter says:

      What Nico said x 1000! Thanks for sharing!

      1. Jordane says:

        What Pieter said x100000 !! Amazing work

        1. Fernando says:

          What Jordane said x10^10

          1. Israel says:

            What Fernando said x10^100

    2. Cosmin says:

      Agreed! :)

      One bug I found: if you tap backspace fast to go back in the folder hierarchy, the breadcrumbs don't update properly. May be fixable with a keyup event?

      1. John Cena says:

        Did you fix the bug?

  2. Drew says:

    LOL - Love the reference in the demo if you go into music > u2 you can see "unwanted album" - I laughed.

  3. Cornélio José Wiedemann says:

    amazing tutorial brow

    Great, great great job hehe
    Cornélio José Wiedemann (TI &amp; DBA)

  4. Fernando says:

    Stunning! Thank you!

  5. Tu says:

    If you could replace Disqus to this current comment system, It would be more easier to reader like me to say thank you to you with this great post

  6. Tom says:

    Really nice job! Totally love it!

  7. kszere says:

    How can set rigidly on the path "files" for example to "Home"?

  8. NiuWang says:

    is this able to work inside of a Modal or DHTML Window?

  9. A. Urban says:

    Doesn´t work with jQuery 1.11.1

  10. Aakash says:

    Really cool !!

  11. George Dontas says:

    It is very nice, but if the file names are not in english, the files are not visible.

  12. mihas7f says:

    Great script !
    I's there possibility to display clicked/selected file in some kind iframe and how to display the whole name of file/folder in the grid?

  13. Imran Khan says:

    Hi, i posted a comment but it didn't published. i wan to ask why is it showing the main files folder in the search?

  14. Thor says:

    cool. love it. will use it.

  15. mai says:

    how to delete a file with this?

  16. Brian says:

    cool script! Anyone modified it to show thumbnails of images instead of .jpg file icon?

    1. TheSmartPoint says:

      If you want to display thumbnails instead of the icon for the JPG files edit the line 332 in the script.js with this code:

      if (fileType == "jpg") {
      	icon = '<div style="display:inline-block;margin:20px 30px 0px 25px;border-radius:8px;width:60px;height:70px;background-position: center center;background-size: cover; background-repeat:no-repeat;background-image: url(' + f.path + ');"></div>';
      } else {
      	icon = '<span class="icon file f-'+fileType+'">.'+fileType+'</span>';
      1. Luka says:

        That is not going to work, you must put image betweeen quotes, like this in line above
        f.path='\'' + f.path + '\'';

      2. chamira says:

        This works, thank you so much!

  17. Martin says:

    How can i make it so i can make a folder in the browser and upload to that folder in my browser? thanks

  18. Cariezas says:

    Very sweet! Is there any possible way I could access password protected FTP with this browser?

    1. Evolution Signs says:

      I'm actually building that functionality now to provide a download area for our clients on the Evolution Signs website that hooks up to the FTP enabled NAS drive in the workshop. I have made quite a few changes and will be using vue rather than jQuery (mainly to help teach myself vue :) )

  19. pdeddy78 says:

    Wow, nice.... Thank you :)

  20. Stan says:

    Thanks for this!

  21. Giorgio Leone says:

    Does anyone found out the way to make it work if the "files" folder is somewhere else (on the same server).

    I tried different things. Even if the scan.php return a correct json, the javascript cannot navigate to the subfolders.

    Any help?

    1. dylan says:

      Giorgio - I have the same issue! Did you solve it?

      1. Gilles says:

        You have to change the 'files' twice in your scan.php. Once at the top and once at the bottom. There you find some json. Now set the 'name' value to your variable $dir that you defined at the top of your scan.php file.

        I've played around with this tutorial and dropzone.js for file upload. Then I've added mixitup jquery plugin and it's insane! :)

  22. aditt says:

    nice script.
    but how about the 'search' function...
    it's not working

  23. andrey says:

    It's really cool! Thanks. Will you plan to add uploader button here? Also I have trouble with files and folders in russian lang - script not working.

  24. Boris says:

    Very good stuff. 1000 thanks for sharing

  25. mhm5000 says:

    make the first "fileType" in line #332 of js file, lowercase so that .JPG, .jpg, .jPg are the same...

  26. Alex says:

    This is just an amazing script! Thank you!!

  27. Jason Davis says:

    I absolutely love this now that I've went over the's awesome! Thanks for sharing with the community. I look forward to seeing other cool JS + PHP projects

  28. Steve says:

    index.html reports "no files here", but scan.php (run directly) returns a directly listing as expected. Bug?

    1. Tanc says:

      I had the same issue until I changed both $dir on line 3 and the hard coded "name" =&gt; "files" on line 63. The javascript uses the 'name' so it needs to match the directory name if you change it.

    2. Andrew says:

      If you make line 63 look like this:
      "name" => basename($dir),

      That will allow the script to function if you change the directory name.

  29. Def says:

    Couple of lines and it even works under IE8 (sadly without search) :-)

    Just add folowing lines to script.js after var definitions:

    if(typeof String.prototype.trim !== 'function') {
    	String.prototype.trim = function() {
    		return this.replace(/^\s+|\s+$/g, ''); 
    if(!Array.isArray) {
    	Array.isArray = function (vArg) {
    		return === "[object Array]";
    if (typeof Array.prototype.forEach != 'function') {
    	Array.prototype.forEach = function(callback){
    		for (var i = 0; i &lt; this.length; i++){
    			callback.apply(this, [this[i], i, this]);
  30. Petr Chubenko says:

    Hey guys,

    Amazing stuff, and I actually went and built off of this, to have the data appear in a table, and everything works but as soon as I try to sort the data, it disappears. Anyone know what that might be? Thanks

  31. robert says:

    thanks for this amazing and easy-to-use software.
    I tried to use it with filenames containing the german umlaut. This files will not be displayed. Does anyone have a solution for this?

    1. Brando Online says:

      I havent gone through the entire script for the naming - just moreso for the directories - but as long as the JSON is being returned from the PHP and its not being displayed in the browser for you to interact with, I would say check the JS file out. You may have to escape that character or turn it into an HTML entity until it hits the browser - that probably doesn't make too much sense - its almost 4am and I've been up 23 hours lol, but most likely it's not acting nicely with jquery or javascript (like I said, as long as the JSON is being return from the PHP AJAX call)

  32. red says:

    Hope this helps somebody. Unfortunately I have to support IE9.

    In order to get this to work in IE9 I did the following:

    1. To prevent quirks:
    2. Replaced all string.trim() calls with $.trim(string)
    3. Put the lines to update window.location.hash in keyup event because IE doesn't detect backspaced/deleted chars in an input event.

    Seems to be working OK, but haven't tested it extensively. Anything I might have missed? Thanks for the really neat little file browser!

    1. lhooq says:

      I, could you share your modified script ?
      Il need to support IE9 too but i'm not a developer.


  33. dylan says:

    I'd love to see a way to protect document urls!

  34. iknowsomething says:

    Superb UX!
    Big missing is the file uploader and file management (rename, delete, move, create folder) to fulfill my needs. It could be the best on the market (currently

  35. Kyle says:

    This looks amazing, but it only useful for a small amount of files or folders. It is way too slow generating the JSON for thousands of files and folders.

  36. Mike Sims says:

    This is a very nice project, though I found it a little frustrating at first, simply because I knew nothing about php, javascript, css or even much of html or any form of linux. But it has been a brisk and exciting week!

    My plan was to install Cute File Browser on a Raspberry Pi to present the files and folders of an attached USB memory stick, to allow my wife to copy files, mostly PDFs, from the stick to an iPad in a Wi-Fi free environment, using Safari or Chrome on the iPad. Something that would be entirely unnecessary with an android tablet. But the oh-so user-friendly iPad?


    The Pi was already set up to run its own Wi-Fi AP to let the iPad's Wi-Fi to connect directly to it, via another project which also had its own php script etc but it was very disappointing to look at, and it was entirely unable to move up and down the directory structure. So I set about replacing that part with the Cute File Browser.

    CFB worked perfectly under Raspbian if I elected to use the default "files" local folder as covered in the article, but I needed it to access the USB stick on /media/usb0, so I duly replaced that path into the two places in scan.php that other commenters have mentioned.

    But CFB always told me "No files here". This was puzzling because any search in the Search field always returned folders and files that were there on the stick anyway, but while the file items thus found were quite accessible, every folder would resolutely return "No files here".

    I found two simple solutions, the easiest of which is just to symbolically-link the files folder to /media/usb0.

    From within the "files" folder (/var/www/files on the Pi), type:

    sudo ln -s /media/usb0

    This works perfectly well, and continues to work when you replace one stick with another. (I always shutdown the Pi first as it can cause power surges.)

    I still wanted to know why the obvious trick didn't work, so there followed some debugging (something else I didn't know how to do last week), resulting in another almost equally simple solution:

    Line 3 in scan.php I replaced "files" with "/media/usb0" as before, because that is the directory that will be scanned. (I have installed usbmount which gives predictable names for inserted sticks.)

    Line 63 in scan.php I replaced "files" with "media" because while that is adopted by script.js as the name of the array variable containing the scanning results, it is also used as the start of an internal pathing structure that has all "/"s removed during the processing of the script, so it has to match the initial directory but without the "/".

    I did make a couple of other changes to the script.js, styles.css and index.html files, not to make CFB work, but basically to allow a remote shutdown option once the session with the iPad is done, to gracefully shut down the Pi which in this scenario has no keyboard, nor any buttons to initiate shutdown on the Pi itself. I'm very pleased with this bit because you merely have to type "closedown" into Cute File Browser's search field in Safari, excluding the quotes and that will trigger the shutdown process on the Pi.

    And I only had to mess with the css and html to display the relevant shutdown instructions to the user.

    1. Harsha says:

      Cheers! Thats what I've been working on too!

  37. Tyruke says:

    I had a problem with some files opening up within the browser. Then I noticed your suggestion of using the .htaccess file to force downloads. It now works flawlessly in Google Chrome and files automatically download. However in Firefox and Microsoft Edge, I can only get PDF files to download, but Mp3 media still plays in the browser.

    However, in your demo site I do not have this problem in Firefox or Microsoft Edge. I'm wondering if it has to do with the files being dummy files.

  38. René says:

    Is there any way to show thumbnails even if there is a blank space between the file dir?

    1. Brando Online says:

      Thats what I'm implementing now. Im using a php script from several older sites that I've build in the past, where the script creates squared thumbnail images on the fly, it has a caching method built into it, so after the first initial load of the thumbnail in the size you choose, it just recalls the cached copy, rather than regenerating it. Google 'PHP cropped image on the fly with cache'.

      You'll need to change this icon variable in the asset/script.js file to an image file, rather the icon.

      Do a search for the first line in the sample below to find the exact location. I just added the line that basically says if the filetype is a jpg, png or gif, overwrite the icon from above and instead use this php script to load a squared thumbnail on the fly.

      if(scannedFiles.length) {

      scannedFiles.forEach(function(f) {

      var fileSize = bytesToSize(f.size),
      name = escapeHTML(,
      fileType = name.split('.'),
      icon = '<span class="icon file"></span>';

      fileType = fileType[fileType.length-1];
      icon = '<span class="icon file f-'+fileType+'">.'+fileType+'</span>';

      if(fileType == 'jpg' || fileType == 'png' || fileType == 'gif'){
      icon = '<img src="../_php/thumb.php?image='+f.path+'&width=150&cropratio=1:1" class="img-thumbnail" />';

      var file = $('<li class="files"><a href="'+ f.path+'" title="'+ f.path +'" class="files">'+icon+'<span class="name">'+ name +'</span> <span class="details">'+fileSize+'</span></a></li>');


  39. Jens says:

    is there a way to use this filemanager two times in a site with two diffrent "files" folders?
    that would be great!

    1. Brando Online says:

      I just implemented this myself in 3 different folders.

      Put your CSS, JS & PHP files in their own folder(s).

      Then put the HTML file in a completely different folder and make sure its labeled index.html - this will allow clean url loads... inside the HTML, be sure to point to the CSS & JS files properly.

      Then go into the JS file do two thing...

      1) set a variable to grab the windows url - this gives the folder name that you want to view files in - lets say you named this var FOLDER before/above the AJAX Get function.

      2) in the AJAX Get function below, add something like this to the url

      $.get('../_php/scan.php?folder='+FOLDER, function(data) {

      Now, jump into the PHP file and do something like this

      if(isset($_GET['FOLDER']) AND $_GET['FOLDER']){
      $dir = "../../".$_GET['FOLDER'];
      $name = explode('/', $_GET['FOLDER']);
      $name = $name[1];
      $dir = "../../members/public";
      $name = "public";

      Your filepaths will be a little different and its usually just a matter of adding or removing the ../

  40. Sebastian says:

    Any way to use this with latest jQuery?

  41. Bedder says:

    URL Payload:
    /cutefilebrowser/index.html#<h1>XSS Attack!

    XSS in index.html -> script.js

    if (i !== breadcrumbsUrls.length - 1) {
    url += '<a href="'+u+'"><span class="folderName">' + name[name.length-1] + '</span></a> <span class="arrow">→</span> ';
    url += '<span class="folderName">' + name[name.length-1] + '</span>';

    1. Mihai says:

      Did you find a fix for this?

  42. Kevin says:

    Hi. Great job!

    Is there any way to open the file in a new tab or in a new window?


    1. Brando Online says:

      Search for the following in your JS file

      var file = $('<li class="files">

      I know its a partial line, but it should be somewhere around lines 330-360 - I've edited quite a bit so I'm not sure what exactly would be on a stock file.

      Just after the text you searched for is the link that is wrapped around the files. If you want the file to open in a new window add the attribute target="_blank"

      so it would look something like this

      var file = $('<li class="files"><a href="'+ f.path+'" target="_blank" title="'+ f.path +'" class="files">'+icon+'<span class="name">'+ name +'</span> <span class="details">'+fileSize+'</span></a></li>');

      1. Kevin says:

        Thanks Brando!

        it works great.


  43. Brando Online says:

    LOVE THIS LIL SCRIPT! Thank you!

  44. bbcluny says:

    How can change name "files" for example to "Home"?

    1. Adam says:

      At the bottom of the Scan.php inside the json response

  45. Oguz Gelal says:

    Hahaha Music -> u2 -> Unwanted Album.. xD loll

  46. Asylbek says:

    It does not work with non English named folders and files

  47. AlbertAlpha says:

    Very nice UX. I used your code as the base to build a little Amazon S3 file browser with folders, edit, upload, and create folder functionalities and extended visualization with thumbnails for images.


    1. Danny Markov says:

      Nice job Albert, it looks awesome!

    2. Cybersoul says:

      Excellent work AlbertAlpha, it's possible can you share your code or project to use it.

    3. Davide Pilato says:

      Hi Albert,
      i'm interest to your fork. Can you share your work?


      1. Daniel Dulaney says:

        Hello! I'm currently working on a version of this with AWS as well, using the PHP AWS API.

        I have it working now with a bucket and then 2 deep subfolders. More currently breaks it, as I'm still working out all of the array building.

        If you're interested, I can update you when it's all cleaned up.

  48. AndreaEm says:

    I got another problem, even if I change directory, the script display nothing, If I call the scan.php file in browser I got the JSON response, but in file browser nothing, what I'm doing wrong?

  49. Cybersoul says:

    Nick, wonderful application, worked perfectly. What impresses me most is the design without images or icons, but i could not find how I can edit the images,i download the "psd" but do not understand how combined with CSS3 and keyframes, you could help me. Thanks

  50. xmodpt says:

    Great work you guys.... love it

    now... question...

    In portugal we use diferent chars like "ç á ã" etc...

    In my php i have set UTF-8 and in my "Files" folder i have 3 files: cao.txt çao.txt and ção.txt.

    If the only file is cao.txt, all work fine but if there are the other 2 files with special chars, nothing shows up.

    Any solution to my problem ?

    Thank you

    1. kim sang gil says:

      hi xmodpt :D
      go to "scan.php"

      $files[] = array(
      "name" => $f,
      "type" => "folder",
      "path" => $dir . '/' . $f,
      "items" => scan($dir . '/' . $f) //

      $files[] = array(
      "name" => iconv("your country encording type", "UTF-8", $f),
      "type" => "folder",
      "path" => iconv("your country encording type", "UTF-8", $dir . '/' . $f),
      "items" => scan($dir . '/' . $f) //

      im korean, then

      "name" => iconv("euc-kr", "UTF-8", $f),

  51. Luiz Reis says:

    Excellent job!! Thank you so much!

    For anyone that can't go with PHP, I've done a .NET C# connector to it, you can get it here:

    Please, feel free to use it and upgrade it.

  52. Charles says:

    After unzipping the zip file. i moved the project folder to my local server and kept some folders into the file folder but when i run the project it says no file

  53. ceejer says:

    I had to change it from
    if(demo[j].name === path[i]) to
    if(demo[j].path === path[i]) in order for it to match when I changed the folder location name.

    Also, fileList.animate({'display':'inline-block'}); to fileList.fadeIn(); in order for it to display

    Finally, folder.appendTo(fileList) to fileList.append(folder)

    Although this may be due to using later version of jQuery

    1. Roger says:

      Man, u save the day! Thank u!

  54. King Mharkley says:

    Hi Nick, thanks for this and it's absolutely awesome.

    Just want to know on how can I delete an item directly? and also is it possible to add a drag and drop feature here?

    Your help or anyone from here will be highly appreciated.

  55. Rob says:

    not sure what the issue is. perhaps i have too many files. i looked at the scan page and it outputs json with a list of all of the files. but the page itself says no files. i specified the path /var/www/html/photos/ ... perhaps this messes with it. i don't want a php file in an area where users upload. maybe you will have an answer. it's a nice little utility function.

    1. craig says:

      you need to change

      echo json_encode(array(

      "name" => "files", //this line here to ur new dir
      "type" => "folder",
      "path" => $dir,
      "items" => $response

      bottem of scan.php

  56. KevC says:

    Like all great solutions, it's simple and elegant - with all the glitter in the css and all the logic in the js; php doing the OS bits it does really well (just watch out for the recursion on big trees)

    but I'm more interested in why there's an if{}else that does the same thing in both branches.
    script.js, lines 172-183

    if (rendered.length) {

    currentPath = hash[0];
    breadcrumbsUrls = generateBreadcrumbs(hash[0]);

    else {
    currentPath = hash[0];
    breadcrumbsUrls = generateBreadcrumbs(hash[0]);

    I must be missing something..

  57. Gary says:

    Hi guys really need your help

    I am using xampp on port 8080 on a local server
    I have installed cute file browser in a folder. the network uses ip
    all works Great.

    problem: We have another ip range that joins the network when they browse the folder the files do not appear.

    Is it a xampp setup i need to look at? Or is it script in cute file browser. Your help will be greatly appreciated.

    Thanking you in advance

  58. Jesus says:

    Hi all,

    Nice tool, really impressive for such small files.

    I just wanted to share a small bug that was making me crazy setting this up for a folder named different than "files".

    At the end of scan.php you'll find:

    echo json_encode( array(
    "name" => "files",
    "type" => "folder",
    "path" => $dir,
    "items" => $response

    "name" => "files"

    should be

    "name" => $dir

    in order to work properly. Of course, $dir should be set in the top of the file accordingly.

  59. PirPyn says:

    On my server i like to have theses soft in a /opt/appsname (eg /opt/cfb) folder when my "files" folder is in /files. So i've changed the js and php code to be able to do so. Also, I added the choice to ignore some file with extention (eg .php file).

    You can check it out on my github

  60. Mukesh Dak says:

    Very nice script, exactly what I wanted.

  61. Matthew Haase says:

    I would like the ability to drag files from the folder displayed to the desktop. Has anyone covered that?


  62. sudipto says:

    i want to show the content of sub folder, for the fist time it working fine but after clicking a folder inside that sub folder the link root folder. i don't want to show the root folder. i changed a lot of thinks to make that happen but its not working. plz help

  63. lesquishy says:

    Hey Everyone.

    I've heard your requests. So I'm going to try my best to complete them while sticking with the design.

    So far I have completed:
    Settings menu (its only use atm is reporting bugs)
    Ability to select items.
    Custom System report (WIP)
    Logging System

    I'm working on:
    Zip and download multiple files at once.

    Planned to add:
    Drag and Drop upload
    Better IE support
    Sign in w/ Permissions
    Hide from users (and or hiding them all together.)
    Maybe more

    I'm also going to try and make it as flexible as possible. So you can enable / disable any of these without it breaking. That's the plan at least.

    As it is so early in development I'm not going to post my GitHub. Don't get too hyped either because I also have a life to maintain and I might not ever finish, when I think it is at a sound / useful stage I will then share.

    Any suggestions, Just reply. :)

  64. Rajesh Rajgor says:

    Hello friends,
    Here is an example to select file from directory/subdirectory as well as to view the file.
    I made this for an email attechment.
    Here it is <a href="">DEMO</a>

Add Comment

Add a Reply

HTML is escaped automatically. Surround code blocks with <pre></pre> for readability.
Perks:   **bold**   __italics__   [some text]( for links